are cookies mandatory for Ruby on Rails app? - ruby-on-rails

is it true that Rails depend on cookies? It seems that flash is a part
of session, and session uses cookies... so when i disable cookie in
Firefox, a Rails app that was working shows
[error]
ActionController::InvalidAuthenticityToken
so is it true that for a RoR app to work, cookies are mandatory?
Update: or, to make the Rails app work again, what is the simplest way? (and if it is one server only (Apache running mod_rails), then is it easier?)

They are not mandatory, but there are some things you can't do without cookies. You can turn the authenticity tokens off as described here.

It's not mandatory to use cookies, but it is the rails default from 2.x up. Using cookies serves as a simple solution to some more difficult problems that arise when you try to store cookies in memory on multiple servers (and you get into things like sticky sessions, losing user data etc).
You can set where rails stores your session data; that is the flash and anything that's associated with the specific user. In environment.rb you can configure where you store your sessions using the config.action_controller.session_store. The options for this are: :cookie_store, :active_record_store, :p_store, :drb_store, :mem_cache_store, or :memory_store.
cookie_store is the default, if you comment the option out or remove it from environemnt.rb. It's also the most versatile. If you have multiple servers, one request for a user might come into one server, and the next request might come into a different server. In this situation, you couldn't use memory_store, as the 2nd server wouldn't know anything about the current user.
By storing session information in an encrypted cookie, there is less load on the server to store this information. The only downside is that each request to the server needs to pass the cookie (usually <1k), but it's not a noticeable difference in anything I've ever experienced.
:cookie_store, :mem_cache_store and :active_record_store are the most commonly used ones.

Related

Rails 3.2 - Writing cookie value without encoding

We have a few web applications that share a cookie value ssoid.
When the user logs into our Rails application, we want to set the ssoid value in the cookie but Rails is URL encoding the value by default.
cookies[:ssoid] = session[:token]
Value written to the cookie store is
ABCpRyan0fLwMamiT%2F9GGk2o%2FAPckq1C8PbHCotxmgUk%3D
instead of
ABCpRyan0fLwMamiT/9GGk2o/APckq1C8PbHCotxmgUk=
Is there a way to avoid this?
I think that you can use the memcached gem to store cookies in one commun place and share that cookie across multiple apps you can also take a look at sharing session across rails apps on different subdomains as a subdomain is seen as a different site or app
I hope that I could help.

How does rails/devise handle cookie sessions?

I'd like to understand what's really going on when signing in a user with rails/devise.
I've created a minimal rails app, installed devise and created a User devise model.
Everything works fine, and when I log in (using remember me) I get a session cookie just as expected.
Now what's bugging me is : How does rails handle the session informations that the browser is passing through the cookie ?
I'd naively expect some information to be stored in the database, but I don't see where. There's no such thing as session table, no session column in Users, and I couldn't find anything of interest in the tmp dir.
Note that restarting the server wouldn't kill my session. It is of course expected, but now I'm really wondering what kind of magic is happening here ?
in other words : how does the server check the validity of a cookie to authenticate a user ?
Thanks !
The default rails session storage is CookieStore. This means that all the session data is stored in a cookie rather than in the database anywhere. In Rails 3.2 the cookie is signed to prevent tampering, but not encrypted. In Rails 4 it's generally encrypted by default. The fact that it's in a cookie is how it persists across restarts of your server. It also means you can only store 4k of data and you wouldn't want to store anything sensitive in there in Rails < 4. It's best to keep a minimum of data in the session anyway.
You can also opt for storing the session data in the database and only having a session id in a cookie.
This answer I gave the other week has some extra info that might be useful:
Sessions made sense to me before I started reading about them online
Also, the rails api doc for CookieStore gives a nice summary:
http://api.rubyonrails.org/classes/ActionDispatch/Session/CookieStore.html

Rails sessions not saving

I'm in the process of upgrading a Rails app from Rails 2 directly to Rails 4. I'm using the new /config/initializers/session_store.rb file, with CookieStore, but for some reason my sessions are not saving.
When trying to do something along the lines of
render :text => "#{request.session_options[:id]}"
I get a new session ID every refresh.
I've tried on different browsers, and all should be accepting cookies.
I have no idea what's going on. Why won't these sessions persist?!
Edit: thank you all for your suggestions. Here's a little more information, and a few things I've noticed:
First, about my set up -- I'm running the server with Rails 4/Ruby 2 through RVM on an Ubuntu VM on my Windows 7 machine.
Although I'm upgrading from Rails 2, that only really applies to the models/controllers/views/etc -- I generated a new Rails 4 application for all of the supporting infrastructure.
I created another application on the same VM that JUST sets a session and then displays, and that works fine.
What the session is storing varies slightly depending on what the user is doing, but usually it holds simply a user id (just an integer), and occasionally a little more -- (i first noticed this manifesting itself while trying to pass an OAuth token from the OAuth gem.)
I've noticed that if the VM's system clock falls behind the Windows 7 host machine clock, the user id sessions hold. That causes other problems, especially with OAuth, but there seems to just be a time issue somewhere. I've tried doing things like removing the time zone from my environments/development.rb, but that did not help.
As a general answer a couple of possible problems are
Session size over 4K limit (which is apparently the case).
CookieOverflow is raised if you attempt to store more than 4K of data.
Please, bear in mind that if you store an object in session, the object is previously serialized before storing it and its size would be bigger. More info on the general problem and possible solutions for the specific problem, here.
Problems with CSRF protection.
If the security token doesn't match what was expected, the session
will be reset
Edit: To check if it is a CSRF case, you can, as Abdo comments below, temporarily disable the protect_from_forgery line in ApplicationController
I had a similar symptoms. It turns out it was because I added the rails-api gem and it totally broke session saving.
From: Railscasts Episode 415 Upgrading to Rails 4
There’s one more configuration change we need to make, in the secret
token initializer. In Rails 4 the configuration option in this file
has been renamed from secret_token to secret_key_base. We’ll need to
specify both options while we’re transitioning from Rails 3 but once
we’ve successfully migrated our application we can remove the
secret_token option. It’s best to use a different token for our
secret_key_base.
This is necessary because we’re moving from a serialized cookie stored
on the client to an encrypted cookie. This prevents users from easily
being able to see the contents of their session cookies.
The episode includes a very good series of tips regarding upgrading from 2 to 4 and I was able to do that successfully using this tutorial.

Is it possible for Rails sessions to be created 'just in time'?

My understanding of the session lifecycle in Ruby on Rails (specifically v3 and upwards) is that a session is created at the start of a request, for each and every request, and if that request doesn't carry an existing session cookie a new one will be created, otherwise the session cookie is deserialized and stored in the session hash.
The purpose of this, of course, supports a number of security features such as CSRF etc.
However, this poses a bit of an issue when it comes to caching of pages in a site with HTTP cache services and proxies such as Varnish, as most of the configurations tend to strip out these (generally all) cookies on both the request and response end (as the cache is usually intended for a generalized audience).
I know that it is possible to setup Varnish etc to create the object hash with the cookie details included, and this would scope the cached data to that session (and therefor that user), however I am wondering if this is completely necessary.
I have an application which is fairly 'static' in nature - content is pulled from a database, rendered into a page which can then be cached - there are a few elements (such as comment count, 'recent' items etc) which can be added in with an ESI, but for every request Rails still tends to want to setup a new session, and when a user already has a session this stuff is stripped out by the cache server.
I am wondering if it might be possible (via pre-existing functionality, or building the functionality myself) to allow the developer to control when a session is required, and only when that is specified is the back-and-forwards with cookies, session initialization/deserialization etc necessary.
That, or I am thinking about this problem the wrong way and need to address the issue from another angle...
From what I know rails sessions can be controlled fairly in-depth via ActionController::SessionManagement
http://ap.rubyonrails.org/classes/ActionController/SessionManagement/ClassMethods.html#M000070
There are examples in the API docs of disabling it per action, per controller, etc.
If your site is mostly static then you may want to use full page caching. This takes Rails out of the request entirely and let's the web server deal with it once the content has been generated. Might cause some serious headaches depending on your exact needs as far as the comment counts and user-specifics though.

Rails, CookieStore vs ActiveRecordStore

I am currently experiencing a strange issue with our users being logged out. I haven't been able to reproduce it explicitly.
The Rails application is using the default CookieStore.
My initial hypothesis is that somehow the session data within the cookie, or even the cookie itself is being destroyed. This may be either from a user clearing browser data, or something within the system that has not been caught.
As of now, the authentication system appears to be functioning as intended (Authlogic), and we are not experiencing the issue wide-spread in other components of the application.
I am considering using ActiveRecordStore to see if the problem is resolved. My understanding is the session data would be stored within the database, and if a cookie was being removed - the user would not get logged out.
Are there many known pros/cons to using CookieStore vs ActiveRecordStore?
Why is CookieStore the default when creating a Rails application, and not ActiveRecordStore?
I can answer your last two questions.
You should not use the cookie store if you're storing sensitive data in the session because you want such data to be on the server-side and not on the client.
The cookie store is the default because Rails is giving you a strong hint that you should not be storing lots of data in the session, by virtue of the fact that cookie storage is limited to 4 KB.
I think CookieStore is the default because it is simple. It doesn't require a database table.
CookieStore is not as secure as ActiveRecordStore. With CookieStore, intercepted cookies will give access to a valid session forever, even if you create a new one. With ActiveRecordStore, you can invalidate a session by removing it from the database.
See this blog post: http://www.bryanrite.com/ruby-on-rails-cookiestore-security-concerns-lifetime-pass/

Resources