Sessions and cookies in Ruby on Rails

An important issue rarely talked about with little documentation on Internet. So, here we go ... a guide to session and cookies in Rails. Session and cookies are an integral part of any good web application and rails has a good support for them. Continuing with our DRY approach, this guide contains link to cool articles with good description wherever necessary.

Table of Contents

  1. Introduction
  2. Sessions
    1. Session in rails
    2. Configure your sessions
    3. Storage options
    4. Session storage limitations
    5. Session and Security
    6. HowTo
      1. Implement session expiration
      2. Delete stale sessions
      3. Find out active users
      4. Access session data using session_id
    7. Miscellaneous
  3. Cookies
    1. Cookie on rails
    2. cookies vs. request.cookies
    3. CookieJar
    4. Miscellaneous


HTTP is a stateless protocol which creates problem in uniquely tracking a visitor to a web application. The process of managing the state between browser and server is through the use of session IDs which uniquely identifies a client browser.

Session IDs can be stored and communicated in one of the following ways :
  1. Embedded in URL
  2. In form field
  3. Using cookies.

Information stored between multiple client browser request is called Session Data. Session data for each visitor can be stored at the server or in cookies. Upon client request to server, session data is extracted from session storage using session ID send by client browser. A good common example for session data is user information for authentication.

In the present times, its hard to imagine a good web application not using Sessions.

A wonderful article on implementation techniques of Session ID.

- Sessions -

Session in rails

Session in rails is a hash-like structure which allows you to store data across requests. Sessions can hold any kind of data object (with some limitations) because they store data using Data Marshalling (aka Data Serialization or Data Deflating).

Rails way of implementing session:
  1. session_id is a 32 hex character MD5 hash based upon time, random number and constant string. It is stored in cookie at client browser. Rails provides transparent support for session_id.
  2. Session storage discussed below.

Remember, you can insert or access values from session similar to hash ... but session is NOT a hash. Most of the other hash methods will not work with sessions.

Working with session in rails Data Serialization in Ruby CGI::Session creates a new instance of session everytime a new user visits your site.

Configure your sessions

Configure key, prefix, expiry and domain of your session. Switch on/off session at controller and action level. session_path and session_secure

Refer to next section on options for session storage.

Note: By default session_id is stored as key in cookies. For multiple rails application from same domain its a good practice to set 'session_key' to avoid conflicts.

Storage options

Ruby on Rails provides you with many session storage option.
  1. PStore
  2. ActiveRecordStore
  3. CookieStore
  4. DRbStore
  5. FileStore
  6. MemoryStore

CookieStore is available only in edge rails. PStore is the default option for stable release, whereas its CookieStore as default for edge rails.

Good description on session stores. Cookie-based session storage Improve performance : use SQLSessionStore instead of ActiveRecordStore Comparison of session storage option

Session storage limitations

Following objects cannot be stored in session storage:
  1. Bindings
  2. Singleton
  3. I/O objects
  4. Procedure objects
Do not store model objects in session
  1. Change in model objects saved in session would also change table row corresponding to model object.
  2. Breaks validations.
  3. On change in class definition, model objects in session will go out of sync.
  4. A general belief is marshalling/unmarshalling of session on each request is expensive. This might be wrong - read Eric Hodel's comment at :

Incase you are storing model objects in session, upon change in class definition you will need to delete sessions and then restart your applications.

More limitations :
  1. Store only user-specific data. Session data will become stale if other users can modify/update it. For e.g. if you store blog comments in session then session of active users need to be explicitly updated when new comment in made.
  2. Critical information should be stored in database and not sessions as you might loose information if client cookie is lost/deleted. For e.g. user purchase information on a shopping site.
  3. Session are not meant for storing massive objects or tons of information, use your application database instead.

Session and Security

A detailed look into security issues concerning sessions. Lookout into sections named as 'Session Hijacking' and 'Common Failings' Minimize session attacks Using XSS attacks a hacker can steal user's session-id ... be careful.


Implement session expiration

A good description A concise version

Delete stale sessions

Every session created in session storage (ActiveReocord, PStore ...) is not deleted upon session expiration or browser close by client. Which means you will have to run a cron job to delete old sessions else your session storage will shoot up in size.

As a good practice disable sessions for those part of your web application which does not require sessions. This will avoid creation and storing unnecessary sessions in your storage.

Find out active users

If you want to find no. of active users, simply use updated_at column of sessions table.

Access session data using session_id

This might be helpful if another application in same domain wants to access your session.


  1. Use model method to access row in sessions table corresponding to current session. For e.g. or session.model.updated_at
  2. Smart plugin for better session experience in rails specially for session expiration.
  3. Flash messages to communicate between actions are stored in sessions. So, if you switch off your sessions, flash messages will stop working.
  4. Do not let bots make unnecessary sessions
  5. Do not write unchanged sessions back to database -- improves performance
  6. Non-cookie session :

    If the client has cookies disabled, the session_id must be included as a parameter of all requests sent by the client to the server. The CGI::Session class will transparently add the session_id as a hidden input field to all forms generated. No built-in support is provided for other mechanisms, such as URL re-writing.

    If you care about browsers which do not support cookies, checkout the following plugins (disclaimer : I have never used these plugins :P )

    Beware, session information in URL might be dangerous. Someone might post a link to a product on a board and everyone following this link is logged with all user data available.

  7. PStore in Windows : Marshal Data Too Short Error

- Cookies -

Cookie on rails

Cookies are stored at client browser and is sent back to server on each request. Rails provides a hash-like structure ActionController#cookies in controller to manage cookies. Session in rails is implemented using cookies.

Description, options and example Note :
  1. Only string can be stored in cookies.
  2. session_id is by default stored in cookies at client browser.

cookies vs. request.cookies

Both cookies and request.cookies are used to access cookie information in your rails application. They are very different in their behavior which can be daunting for beginners. Examples below explains the basic difference between them.

## cookies and request.cookies are different
cookies.class #=> ActionController::CookieJar
request.cookies #=> Hash

## how to access value from cookies and request.cookies
# First set some value in cookies
cookies[:key] = "value"

cookies["key"] #=> "value"
cookies[:key] #=> "value"
# both the output are of type String

request.cookies["key"] #=> "value"
request.cookies["key"].class #=> CGI::Cookie

request.cookies[:key].empty? #=> true
request.cookies[:key].class #=> Array


cookies in rails is of type CookieJar. CookieJar manages incoming and outgoing cookie information and works as follows.

def index
  cookies[:key] = "val"
  puts cookies[:key]
  redirect_to :second_index

def second_index
  cookies[:key] = "newval"
  puts cookies[:key]

## Output :
## Open index page for the first time
# nil
# val

## Open index page the second time
# newval
# val
cookies[] gives you value from the incoming cookie.
cookies[]= sets value in the outgoing cookie.

Reference :


Checkout cookie based session store explained above.

Testing cookies Open ticket - making CookieJar behave like a Hash. Performance and cookies : a good read
Tagged as  
Posted on 21 October
15 comment Bookmark   AddThis Social Bookmark Button Updated on 23 February

Leave a response

  1. jeffOctober 23, 2007 @ 08:31 PM

    shouldn’t the output of the cookies experiment be this?

    1. Output :
    2. Open index page for the first time
    1. nil
    2. val
    1. Open index page the second time
    1. newval
    2. val
  2. QuarkOctober 24, 2007 @ 02:59 AM


    oops! ... was in a hurry to post this article.

    thanks for pointing it out :)

    Ticket #1(defect) closed by quark :D

  3. ManikOctober 25, 2007 @ 10:44 AM

    Nice exhaustive post!

    Thanks for all the info.

  4. Greg WillitsNovember 03, 2007 @ 05:05 AM

    Lots of details. Thanks.

    How do you go about forcing a rails session cookie to be deleted? On a logout page, the cookie should be updated with a negative expiration time so that a redirect off of the logout page result in the cookie being deleted. I haven’t found that documented anywhere.

    Likewise the data column of the session should be deleted when a session is terminated, but I don’t see Rails doing that.

  5. QuarkNovember 05, 2007 @ 03:09 PM

    Hi @Greg,

    Try to use reset_session on user logout. It clears out the current user session and initialize a new session object.

    You are right, on session termination, rails does not deletes the corresponding row from the sessions table. Running a cron job is a good solution. Checkout section ‘Delete stale session’ of this article

  6. Michael HendrickxNovember 09, 2007 @ 08:41 PM

    Nice article, thank you!

    One question though, how do you access the session ID itself? I’m currently using request.cookies[“_appname_session_id”], but it comes with a helluva lot of white spaces.

    I tried casting it in a string, but it gives me the entire cookie contents then.. :(

    Could you help me out please? Thank you and keep up the great work!


  7. Song, ChihyungDecember 18, 2007 @ 09:08 AM

    Hi @Michael, thanks for a good article!

  8. QuarkDecember 18, 2007 @ 10:13 AM

    Hi @Michael,

    session.session_id will give you the session_id.

    request.cookies[“_appname_session_id”] returns session_id in a object of type CGI::Cookie and .to_s on it returns “_appname_session_id=49d8…..f227; path=” this is weird.”

  9. justinJanuary 10, 2008 @ 01:50 AM

    Quark, Would you know how to send session data in GET or how to open the right session data in a controller?

    I'm trying to use FancyUpload ( to allow my users to upload more than one file at a time.  But it requires sending cookie data with GET.  I've figured out how to read the session files, but they are named differently than the cookie ID.

    I’ve been looking in CGI, but to no avail.

  10. QuarkJanuary 11, 2008 @ 06:41 AM


    Rails automatically gets the right session for you. Session-id in present in the cookie, which is a part of every request. So you never need to care about ‘cookies’, ‘session-id’ , etc. Just use session object in your controller.

    If there is something particular do let me know.

    - Quark

  11. NJ - NYApril 12, 2008 @ 05:18 PM


  12. ericApril 22, 2008 @ 06:54 PM

    how can I have multiple rails apps on my intranet use sessions for single sign on?

  13. HatemSeptember 18, 2008 @ 06:07 AM

    Hi, I’m planning to use a reverse proxy on production. When I use Firebug to watch the response headers, I see that a header of “Set-Cookie” is set with the same session id on every request.

    Now, with every request from the same user, the reverse proxy will always think it is a new session and hence prevent caching and affect the performance.

    As I understand, the server should set a cookie if the user is new (has no cookies) or their cookie is expired. Is that correct? So why does Rails keep setting the same on each request? or is the default timeout is one second?

    Please help me to fix this. Thank you.

  14. Andre DuraoFebruary 20, 2009 @ 01:03 PM

    Hi there I found your article very good, I’ve been looking for a way to solve this perhaps you could give me some hint

    “Is there some way to call a function after a session is closed, something like an after_save method in a model?”

    I’ve been looking in a lot of places but still could find no answer..

    Thanks anyway, good article here