Table of Contents
Introduction
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 :- Embedded in URL
- In form field
- 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:- 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.
- 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_secureRefer 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.- PStore
- ActiveRecordStore
- CookieStore
- DRbStore
- FileStore
- 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 storagehttp://www.caboo.se/articles/2007/2/21/new-controversial-default-rails-session-storage-cookies
http://agilewebdevelopment.com/plugins/sql_session_store
Session storage limitations
Following objects cannot be stored in session storage:- Bindings
- Singleton
- I/O objects
- Procedure objects
- Change in model objects saved in session would also change table row corresponding to model object.
- Breaks validations.
- On change in class definition, model objects in session will go out of sync.
http://railscasts.com/episodes/13 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/268624
- A general belief is marshalling/unmarshalling of session on each request is expensive. This might be wrong - read Eric Hodel's comment at :
http://www.caboo.se/articles/2007/2/21/new-controversial-...-cookies#comment-1331Incase 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 :- 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.
- 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.
- 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.HowTo
Implement session expiration
A good description A concise versionDelete 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.Miscellaneous
- Use model method to access row in sessions table corresponding to current session. For e.g.
session.model.idorsession.model.updated_at - Smart plugin for better session experience in rails specially for session expiration.
- Flash messages to communicate between actions are stored in sessions. So, if you switch off your sessions, flash messages will stop working.
- Do not let bots make unnecessary sessions
- Do not write unchanged sessions back to database -- improves performance
- 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 )Hidden Field Session : http://agilewebdevelopment.com/plugins/hidden_field_session
No cookie session support : http://www.edgesoft.ca/blog/read/2Beware, 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.
- 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 :- Only string can be stored in cookies.
- 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.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
## 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
CookieJar
cookies in rails is of type CookieJar. CookieJar manages incoming and outgoing cookie information and works as follows.
So,1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
def index cookies[:key] = "val" puts cookies[:key] redirect_to :second_index end def second_index cookies[:key] = "newval" puts cookies[:key] end ## 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 :Miscellaneous
Checkout cookie based session store explained above.
Testing cookies Open ticket - making CookieJar behave like a Hash. Performance and cookies : a good readComments
- A general belief is marshalling/unmarshalling of session on each request is expensive. This might be wrong - read Eric Hodel's comment at :

shouldn’t the output of the cookies experiment be this?
@jeff
oops! ... was in a hurry to post this article.
thanks for pointing it out :)
Ticket #1(defect) closed by quark :D
Nice exhaustive post!
Thanks for all the info.
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.
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 http://www.quarkruby.com/2007/10/21/sessions-and-cookies-in-ruby-on-rails#sstale
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!
m1ke
Hi @Michael, thanks for a good article!
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.”
Quark, Would you know how to send session data in GET or how to open the right session data in a controller?
I’ve been looking in CGI, but to no avail.
@justin,
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
thanks
how can I have multiple rails apps on my intranet use sessions for single sign on?
LKL;P;KL
IT IS GOOD