Rack & Ruby on Rails: Force SSL

Nowadays, your Web app likely needs security and encryption with SSL. Once your SSL certificate and Web server are set up, one good way to ensure SSL is used is to redirect all HTTP traffic to HTTPS.

In the world of Ruby, I’ll explain how to do it for any application running with Rack or anything built with Ruby on Rails. Your Ruby on Rails application is probably running on top of Rack anyway, so the odds are you just need one of the two methods below.

Both techniques are using environment variables to enable features as I explained in another article. In this case, I’m using the FORCE_SSL variable: if it is set to '1', it means the app should force the usage of SSL connections all the time.

Force SSL with Rack

All you need to do is use the rack-ssl gem and add a line in config.ru:

  • Add this line in your Gemfile:

    gem 'rack-ssl'
    
  • Update your installation of gems:

    $ bundle install
    
  • Add this line to config.ru:

    use Rack::SSL if ENV['FORCE_SSL'] == '1'
    
  • Don’t forget to set FORCE_SSL among the environment variables for the app:

    FORCE_SSL=1
    

Chances are you want to go with this method. Many apps on different frameworks like Ruby on Rails or Sinatra is using Rack as the Web middleware between the actual application and what the Web server, such as nginx or Passenger for Apache. Heroku also uses Rack with the Unicorn Web server to serve Ruby on Rails apps.

This way, forcing SSL connections is handled by that intermediate layer rather than the app itself, so you generally won’t have to worry about making your app aware of SSL connections.

Additionally, rack-ssl is enabling a few other nice security features:

  • Flag all cookies as “secure.”
  • Set Strict-Transport-Security (HSTS) header: a way to tell the browser to only use HTTPS connections and skip redirections on subsequent visits to the HTTP site.

Force SSL with Ruby on Rails

If for some reason you have a Ruby on Rails app, yet cannot use Rack, you can always set the app itself to force SSL connections. Simply add an initializer file:

  • Save the following in config/initializers/ssl.rb:

    Rails.application.configure do
      config.force_ssl = (ENV['FORCE_SSL'] == '1')
    end
    
  • Don’t forget to set FORCE_SSL among the environment variables for the app:

    FORCE_SSL=1
    

It is not as automatic as using rack-ssl, but you don’t need any extra gems for this. There are probably ways to implement HSTS and secure cookies with this too, but I didn’t have a need to look into doing so, as I always use Rack. These missing bits aside, it does the job just fine, which is to redirect all HTTP connections to HTTPS.

Now that you see redirecting HTTP traffic to HTTPS isn’t a hard thing to do with Rack or Ruby on Rails, you have no excuse not to do it now. 😛

Lock image shown in banner made by user Hk kng and available in Wikimedia Commons.

Leave a Reply