#Rails 3 Custom Session Store
Brad Pauly — February 2, 2013

Session management is a key part of web applications, yet frameworks like Rails make it so easy to implement that we don’t give it much thought. In fact, with rails you don’t have to think about it, session management is built into a default app. It’s done by using cookies, which is nice and easy, but is not very secure. Many apps end up storing sessions in a database with ActiveRecord::SessionStore. Run a few commands and voilà, you’re storing sessions in a database. I admit that I don’t give session management as much consideration as I used to so I decided to put my session hat back on and write my own session storage engine for rails.

###It’s easy

Yep, even writing your own is simple with the hooks that rails provides. The only tricky part was figuring out which class to inherit from. All you need to do is inherit from ActionDispatch::Session::AbstractStore and implement three methods. Below is the entire class.

<script src="https://gist.github.com/d20dc680083d1eb9d76a.js"></script>

###For educational purposes only

I’m sure you wouldn’t use this for anything serious, right? But if you feel like playing around I recommend doing it. You can build a simple app and watch it work in a few steps.

  1. Create a new rails app

     $ rails new session_test
  2. Grab the gist and put it in lib/custom_file_store.rb

     $ cd session_test
     $ curl https://gist.github.com/raw/d20dc680083d1eb9d76a/c5e2de0f18384a48e1bbe1178804e887c3a7c366/custom_file_store.rb >> lib/custom_file_store.rb
  3. Configure your app to use it in config/initializers/session_store.rb

     SessionTest::Application.config.session_store :custom_file_store
  4. Make sure the lib directory is auto loaded with this line in config/application.rb

     config.autoload_paths += %W(#{config.root}/lib)
  5. Add an index method to app/controllers/application_controller.rb and assign a session variable.

     def index
     	session[:foo] = SecureRandom.hex(32)
     	render :text => ‘Hi.’
  6. Make the default route point to the index action in config/routes.rb

     root :to => 'application#index'
  7. Remove public/index.html and start the server.

     $ rm public/index.html
     $ rails s

Go to http://localhost:3000/ in your browser or with curl. Now take a look in the tmp/sessions directory. You should see something like this:

Screen Shot 2013-02-01 at 12.56.26 PM

Hooray! You have an app with a file based session store. Open the file with a text editor to see what a stored session looks like.

###Have some more fun

Want to see how this could quickly become a problem in a production environment? Start the rails console or and irb session and do something like this.

require "net/http"
uri = URI.parse("http://localhost:3000/")
1000.times { Net::HTTP.get_response(uri) }

Files are accumulating fast. This is a simple example and doesn’t account destroying sessions, which would happen if you you had an action that destroyed them and it was actually used. Rails uses sessions to store things like flash messages so even if you don’t have people “logging in” and “logging out” you could end up with many many files that you don’t want.

I encourage you to experiment and see what you discover!

Want new posts sent to your email?

I'm always looking for new topics to write about. Stuck on a problem or working on something interesting? You can reach me on Twitter @bradpauly or send me an email.