Making Django and Rails Play Nice, Part 2: Sharing Sessions
Tuesday, March 13, 2012, at 08:47AM
Yesterday I introduced some of the challenges faced in development of KPCC's new beta web site, which is running Django and Ruby on Rails side-by-side during a slow transition from one framework to the other. Part one focused on using MySQL views to allow Django's generic relationships and Rails' polymorphic relations to use the same data.
Today's topic is sessions, specifically how to allow a session to seamlessly pass from one backend to the other.
There are two basic approaches to user sessions: You can either store the data on the server, and give the client just a lookup ID, or you can store the data in the client's browser via cookies.
While either can be the right choice depending on your user count and the secrecy of data you need to store in the session, for our purposes we wanted a cookie session.
While that's been the default session type on Rails since 2.0, they're a new addition to Django in the upcoming 1.4 release. There is plenty of non-core code out there for those on earlier versions, however.
I decided to base off of the Rails sessions, which use Base64-encoded data and a secure digest to make sure the session isn't tampered with.
Off the bat, though, there was one big issue: Rails and Django both use serializers to allow you to throw whatever you want in the session. For Rails that means using Ruby's Marshal, and for Django that means Python's Pickle.
Neither of those were going to work for my purposes (though I have since started using rubypython and pickle to write some Django caches out of Rails), so I replaced both with a simple JSON serialization. That limits we to storing data, not complex objects, but that's an acceptable tradeoff for us.
One last thing to remember: you have to give both apps the same secret key! Easy to forget this one at first and then sit there scratching your head and wondering why nothing works. Not that I've ever done that, of course...
Next up: An object-based approach to caching, allowing us to expire data in both frameworks in one command.
Rails Session Code
Installed via placement in config/initializers/sessionstore.rb._
Django Session Code
Called via the
SESSION_ENGINE variable in settings.py.