Thursday, July 28, 2011

Getting SSL, Capybara, Rails 3, and Devise to work together

I've noticed a lot of Rails blog posts recommending that you only turn SSL on in production and don't try to use it in the test or development environments. This is a monumental mistake, a lesson I learned hard in the early days of OtherInbox: SSL enforcement has a lot of subtleties and corner cases that need to be exercised and tested on a routine basis. As a quick slightly embarrasing example, we had a bug at OIB where flash messages would get swallowed during redirects. It turned out we were accidentally redirecting people to an http:// page, where the flash would be available, but our SSL enforcement code redirected them quickly to https://, and that second redirect ate the flash message. Since we couldn't reproduce the bug on our own machines it was much harder to track down than you would think.

But I know why the bloggers recommend the naive approach though: getting SSL to work offline is a major pain! Right now I'm building a Rails app that enforces SSL on every page. It's all private data (the public-facing site is managed by a separate CMS) so I don't want any page to be accessible over http://. Below is a summary of the code changes I had to make to get this to work. I was mainly guided by this great Collective Idea blog post about Rails 3 SSL that I'd recommend you start with.

It's not hard to get SSL working in development mode if you use an app container like Phusion Passenger. I explained how to do that a few years ago with an Apache-Mongrel setup, but the basic ideas apply.

Update 1/31/2012: I wrote up an easy way to get SSL working with Unicorn and Pound instead of Passenger which is my new preferred way of working. Also check out the Devise wiki for more useful SSL info.

No comments: