How do you handle session data with ActionCable? - ruby-on-rails

I'm building an app using Vue and Rails.
I have both the frontend and the backend separate (in separate folders)
The frontend is generated with vue-cli.
I have a situation where, I want to send some data to the backend via websockets, I want to set that data in something like a session object, and then access that data again on subsequent websocket interactions. Is that possible?
Would I need to set some kind of token in the browser, some kind of identifying token?
This seems like it would be a common problem but I can't find any information on it.

If you are utilizing session in rails websocket/connection.rb you won't be able to access it directly, but you can access it through the cookies object. The rails docs say this is labeled ['_session'] but for me on my browser it was ['_session_id'] then whatever data you set within session like a user id ['user_id']
cookies.encrypted['_session_id']['YOUR_DATA']

Related

How to track a user's session without requiring them to login with ruby on rails

I have an application that has an actual map of objects that any visitor can view as long as they have the correct access code. I don't require the user to login because I don't want to make them create an account as it is unnecessary. I want to allow the users to mark the objects on the map with a check and save the edits within the session. So if the user refreshed the page or they close the application and reopen it an hour or so later, I would like to save their marks based off their session id. But I am confused on how to set this up without requiring them to login because I am unsure how the sessions would work.
Any help would be greatly appreciated!
Sessions in Rails work the exact same way regardless if you have a proper authentication system or not.
When a first time visitor visits your application the sessions middleware creates a session identifier. This is a cryptographic hash that is kept by the server and also passed to the user in a cookie.
This lets you identify users across requests.
This session identifier is also linked to a session storage. By default this is ActionDispatch::Session::CookieStore which lets you store session data in a encrypted cookie held by the client. This is where you would normally store a user id. Since its a cookie the amount of storage space is very limited. If you want to store more data in the session you can use a different store such as Memcached, Redis or ActiveRecord.
But what you may want to consider is creating (guest) user records implicitly without the normal sign up procedure. I would just use Warden and have a bare bones user model and a cron tab that cleans out unneeded data periodically.
This gives you a database oriented application model where you can use associations and build it like a standard rails application instead of the untestable mess that results when someone goes bonkers with sessions.
I would implement Cookies (with their permission of course). You can store basic data in it, or even create a sort of ID for them so when they return you can restore their settings

How to authenticate Rails application using token from 3rd party API?

I have a Rails application that make several user-specific calls to a third-party API. They interact with a lot of data in the course of filling out a survey, and their progress is stored in HTML5 localStorage until they reach the end of the survey and the data is saved in a local database & localStorage cleared.
The API calls require a token tacked onto the end as an "auth=" parameter. Right now, I have the user log into my app with their username and password to that service, POST those credentials to the "sessions" call of that API, and get a token back in JSON. I store that token in a variable in the controller, and use it to make the successive API calls and present the user's data in my app, etc. etc.
I've learned quite a bit about Rails, but next to nothing about sessions or authentication. Generally speaking, is there anything more I need to do for this to be a secure scenario? I feel like I'm missing something.
Assuming the user's username / password combination for the 3rd party service doesn't hit your servers, seems OK to me.
If your servers see the user's credentials, that's not particularly cool. Instead use OAuth to get 3rd party sign in, and use the token to make requests on behalf of the user. You can usually keep the whole session on the client if you want to avoid saving users to the database.
Storing progress in localstorage sounds fine btw. To preserve values you can have the pages of the form be tabs (so hide the previous form, not a new page) and use:
autocomplete="on"
to signify that the values should be restored to what they were. Try that before writing code to save things to localstorage.

RestKit session management

What is the correct way of making "persistent" session with RestKit?
The most simple way is to make long session at the server side, but
not sure it's safe for browser version. I prefer to implicitly re-
login if session is expired, but in this case I have to handle session
expiration, send new login request, receive response and than send
again a target request. Sources become more complicated.
Is there any features in the RestKit which allows manage that
automatically? Maybe just keep persistent session for iPhone app and
short one for web version using features of CakePHP?
Thanks,
Victor
You probably want the session in order to for authentication/authorization to work?
I'm currently working on a RestKit project on iOS. For my needs, what I did was very close to the discussionboard example by RestKit's creators.
in iOS, you can write a uniqueSecurityToken to NSUserDefaults. It can be a property model of your user model on the iOS app. On Rails (Im making an assumption), if you have a auth gem like Authlogic/Sorcery, it's very easy to either override the current_user method or assigning one based on token.
For example,
def user_access_token
request.headers["HTTP_X_USER_ACCESS_TOKEN"] || request.headers["HTTP_USER_ACCESS_TOKEN"]
end
def check_for_mobile_token
if token = user_access_token
current_user = User.find_by_remember_me_token(token) || current_user
end
end
You can call a before filter to make sure that the authentication is always checked. on the IOS side, tell RestKit to send the uniqueSecurityToken as HTTP_USER_ACCESS_TOKEN in the headers. Note that this is probably not the most secure method, you should at least have HTTPS so that the transport is encrypted.
Here's the RestKit Discussion Board Project (very useful for RestKit/IOS)
https://github.com/RestKit/RKDiscussionBoard
Here's a Rails Presentation that outlines Rails/iOS integration
http://www.slideshare.net/maximeguilbot/rails-as-ios-application-backend
If you're using another REST framework other than Rails, you can reference the JSON techniques too.
Probably what you'll want to do is develop a "RESTful" API that your app will use to talk to your server. A REST API, basically, lets the client send up all information that is needed to build state on the server. You shouldn't need to deal with sessions on the server for the iOS app.
The basic idea is that you can get some sort of auth token from the server when you log in. Then you can send that up with every request as a way of identifying the logged in user to your server.

Building RESTful API with MVC for an iPhone app - How to secure it?

I'm going to be writing the services for an iPhone app being built by a third party vendor.
I'll be using ASP.NET MVC to accept posts and also return JSON formatted data.
My question is, how do you secure it?
Just using an API key perhaps? Would that be enough to ensure that only data from the iPhone apps are allowed to hit the specified services?
I'm sort of struggling with the same concepts myself. I think the first thing is to do HTTPS only, so that it's starting out more secure than not.
Next, it depends on how you're going to do authentication. If all you need is an API key, (to track which entity is accessing the data) that should be fine. If you also want to track user information, you'll need some way to associate that specific API keys can access specific types of records, based on a join somewhere.
I'm looking at doing forms auth on my app, and using an auth cookie. Fortunately ASP.NET on IIS can do a lot of that heavy lifting for you.
Example time: (I'm sure I'll need to add more to this, but while I'm at work it gives something to gnaw on)
Forms auth:
Send a pair (or more) of fields in a form body. This is POST through and through. There's no amount of non-reversible hashing that can make this secure. To secure it you must either always be behind a firewall from all intruding eyes (yeah right) or you must be over HTTPS. Simple enough.
Basic auth:
Send a base64 encoded string of "username:password" over the wire as part of the header. Note that base64 is to secure as a screen door is to a submarine. You do not want it to be unsecured. HTTPS is required.
API key:
This says that an app is supposedly XYZ. This should be private. This has nothing to do with users. Preferably is that at the time that the API key is requested, a public key is shared with the API grantor, allowing the API key to be encoded on transit, thus ensuring that it stays private but still proves the source as who they are. This can get complicated, but because there is an application process and because it won't change from the vendor, this can be done over HTTP. This does not mean per-user, this means per-developing-company-that-uses-your-api.
So what you want to have happen is that for the app accessing your data, that you want to make sure it's an authorized app, you can do negotiation using private keys for signing at runtime. This ensures that you're talking to the app you want to talk to. But remember, this does not mean that the user is who they say they are.
HOWEVER.
What you can do is you can use the API key and the associated public/private keys to encode the username and password information for sending them over the wire using HTTP. This is very similar to how HTTPS works but you're only encrypting the sensitive part of the message.
But to let a user track their information, you're going to have to assign a token based on login based on a user. So let them login, send the data over the wire using the appropriate system, then return some unique identifier that represents the user back to the app. Let the app then send that information every time that you are doing user specific tasks. (generally all the time).
The way you send it over the wire is you tell the client to set a cookie, and all the httpClient implementations I've ever seen know that when they make a request to the server, they send back all cookies the server has ever set that are still valid. It just happens for you. So you set a cookie on your response on the server that contains whatever information you need to communicate with the client by.
HTH, ask me more questions so we can refine this further.
One option would be to use forms authentication and use the authentication cookie. Also, make sure all the service calls are being sent over SSL.

How should my main web application (A) securely retrieve data from my content storage web application (B)?

I have two web applications (A) and (B).
(A) is my primary web application.
(B) is purely for content storage, such as file uploads by users of (A).
What's best way to securely retrieve data from (B) into (A) but in a way that does not expose the data in (B) to potential discovery by third-parties over the public internet or nosy users of (A)?
For example, if I use a HTML form POST from (A) to (B) to retrieve user data, and have a hidden form field called user_id=1, then someone could simply change this to user_id=2 and see the content owned by another user of the application. That would be a problem.
You should maybe consider basic authentication (username/password) for authenticating users. System (A) will then use a username and password to authentication itself with system (B).
To secure the username and password (which are part of the HTTP request), use HTTPS. Otherwise this data will be sent in clear text.
if you have a proper database in the back somewhere, you can use that to validate the access privilege of the requesting user (also depends on the type of connection pool you are using i suppose).
I believe You are mixing conceptes. Access to data is one thing, and url's that give user that access is another. You have to describe problem further, we don't even know if those applications use database.
You could use Oauth http://oauth.net/
http://apiwiki.twitter.com/OAuth-FAQ
http://oauth.rubyforge.org/

Resources