Session cookie expiration time in Rails
By default Rails do not support setting expiration of session cookies to ” after last visit”. The code at Rails wiki shows how to set up cookie expiration for a whole application, but it does not support setting this per-controller (or per-action) like other session options, due to the use of class variables.
This became a problem for us recently, as I needed to set different session cookie expiration times for different controllers.
Here is the solution, rewritten from scratch:
# -- put this into vendor/plugins/sliding_sessions/init.rb --
module SlidingSessions
# Allows using :session_expires_after option for session cookies
# NOTE it does not perform any checks on server-side, it just
# sets the session cookie expiration time.
# see http://wiki.rubyonrails.org/rails/pages/HowtoChangeSessionOptions
# for a recipe to perform server-side expiration checks
# (C) Paweł Stradomski , released under MIT licence
def self.extended(base)
class << base
alias_method :session_options_for_without_sliding, :session_options_for
alias_method :session_options_for, :session_options_for_with_sliding
end
end
def session_options_for_with_sliding(request, action) #:nodoc:
opts = session_options_for_without_sliding(request, action)
if opts[:session_expires_after] then
opts[:session_expires] = Time.now + opts[:session_expires_after]
end
opts
end
end
ActionController::Base.extend(SlidingSessions)
# — end of vendor/plugins/sliding_sessions/init.rb –
The above code (module definition + ActionController::Base.extend(SlidingSessions)) should be put into vendor/plugins/sliding_sessions/init.rb
Now you can use
session :session_expires_after => 8.hour # in any controller
in any of your controllers, even application.rb
Of course it only deals with session cookies, you still need to perform server-side checks for expired sessions and write a cron job to remove stale sessions.
December 25, 2007 at 8:33 am
Hi,
this solution seem to bee much better than the CGI::Session plugin. Yet, I can’t figure out where should I put that code. I tried to put it application.rb but it seem that I get an endless loop => calling from session_options_for_with_sliding to session_options_for_without_sliding aliased to session_options_for which is aliased to session_options_for_with_sliding.
I would appreciate if you could help me with that.
Thanks,
Alex Golubev.
December 26, 2007 at 4:30 pm
Updated the text a bit to show where to put the code (vendor/plugins/sliding_sessions/init.rb - you’ll need to create the ’sliding_sessions’ directory).
It’s also available now at http://www.ii.uj.edu.pl/~stradoms/squarewheel/sliding_sessions.zip (I’ve just learnt that I can’t upload zips to wordpress, so it’s on my university account now. I’ll look for a better place later).
January 3, 2008 at 8:12 am
I have done all the things you have said, and wrote the following code in application.rb, but the code is not doing anything
session :session_expires_after => 1.minute, :after_expiration => :some_method
Please help
January 3, 2008 at 5:02 pm
I don’t know why you expect
after_expiration => :some_methodto work. I’ve just grepped through rails source code - and found no file containingafter_expiration.Anyway, I just created an empty rails project (with rails 1.2.6), unpacked the zip above into vendor/plugins (so I had vendor/plugins/sliding_sessions/init.rb file) and added session
:session_expires_after => 1.minuteto application.rb. Checking the cookie with firefox clearly shows it expires after 1 minute, so my patch works as advertised.I’ve also checked with rails 2.0.1 and it still works without any modification.
January 23, 2008 at 8:31 am
squarewheel many thanks, this one is working great