Cookies vs Sessions with CookieStore
In Rails 3, what is the difference between storing data in a cookie and storing data in a session, with the session store set to the default of CookieStore?
e.g.
cookie[:foo] = 'bar'
# MyApp::Application.config.session_store :cookie_store, key: '_myapp_session'
session[:foo] = 'bar'
As far as I can tell, both end up stored in a client-side cookie.
When would you choose to use one over the other?
Thanks.
Solution 1:
The main difference, in Rails 3, is that when you use cookie[:foo] = 'bar'
the user is able to see the value for the cookie, i.e. 'bar'
. When you use session[:foo] = 'bar'
the value will be encrypted by rails and stored in the _myapp_session
cookie.
You would use the cookie[]
format when the information you want to store is not bound to the session, e.g. when the users selects the preferred language.
You would use the session[]
format when you want to store information that is related to the current session, e.g. the id
of the the user.
From Rails 4 cookies became encrypted by default.
Solution 2:
Rails provides several storage mechanisms for the session hashes. The most important are ActiveRecord::SessionStore
and ActionDispatch::Session::CookieStore
.
There are a number of session storages, i.e. where Rails saves the session hash and session id. Most real-live applications choose ActiveRecord::SessionStore
(or one of its derivatives) over file storage due to performance and maintenance reasons. ActiveRecord::SessionStore
keeps the session id and hash in a database table and saves and retrieves the hash on every request.
Rails 2 introduced a new default session storage, CookieStore
. CookieStore
saves the session hash directly in a cookie on the client-side. The server retrieves the session hash from the cookie and eliminates the need for a session id. That will greatly increase the speed of the application, but it is a controversial storage option and you have to think about the security implications of it:
Cookies imply a strict size limit of 4kB. This is fine as you should not store large amounts of data in a session anyway, as described before. Storing the current user’s database id in a session is usually ok. The client can see everything you store in a session, because it is stored in clear-text (actually Base64-encoded, so not encrypted). So, of course, you don’t want to store any secrets here. To prevent session hash tampering, a digest is calculated from the session with a server-side secret and inserted into the end of the cookie. That means the security of this storage depends on this secret (and on the digest algorithm, which defaults to SHA512, which has not been compromised, yet). So don’t use a trivial secret, i.e. a word from a dictionary, or one which is shorter than 30 characters