February 28, 2008

The “remember me” checkbox

Here's a nifty solution that I came up with for implementing the "remember me" checkbox on login forms in Rails.

First you'll need this extension to CGI::Session::CookieStore:

# This adds the ability to dynamically set the expiry on session cookies,
# so that a session can persists across browser restarts.
#
# In your controller, just do something like:
#
#   session[:expires] = 2.weeks.from_now
#
# The expiry is also stored in the session, and double checked when the
# cookie is loaded to prevent malicious reuse of old cookies.
class CGI::Session::ExpiringCookieStore < CGI::Session::CookieStore
  def unmarshal(cookie)
    session = super(cookie)
    session = nil if session && session[:expires] && session[:expires] <= Time.now
    session
  end

  def write_cookie(options)
    options["expires"] = @data[:expires] if @data
    super(options)
  end
end

You'll need to change the session store in your environment.rb:

config.action_controller.session_store = :expiring_cookie_store

In your controller, if the "remember me" checkbox is set, just do this:

session[:expires] = 2.weeks.from_now

Voilà! Now your session (which also holds the id of the logged in user, if you implement logins in the usual way) will stick around for up to 2 weeks, even between browser restarts.

(Obviously this only works with the cookie-based session store.)

If you spot any problems or security holes with this, please let me know.

Where do I put the extension?

October 17, 2008

You can put it in an initialiser, or put it in the lib directory and require from an initialiser. Wherever you like really!

October 17, 2008
  1. Use Markdown for formatting.

  2. I’ll keep your email address private.