back

Using SSL in Rails 3

Update

read this article instead

tl;dr

Use this version of ssl_requiment or this middleware gem

Forcing SSL in a scope

This will only allow https in production.

1
2
3
4
5

scope :constraints => { :protocol => Rails.env.production? ? 'https'  : 'http' } do 
  resources :secrets
end

This sucks because when you do:

1
2
3

<%= link_to secrets_path %>

You will have to manually specific the protocol, since http://host.tld/secrets will 404. I.e. this only creates the https route.

An SSL constraints class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# config/routes.rb

SSLApp::Application.routes.draw do 
  class SSL 
    def self.matches?(request) 
      return true if Rails.env.development?
      request.ssl? 
    end 
  end 
 
  scope :constraints => SSL do 
    resources :secrets 
  end 
end 

This is basically the same thing as the first one, but it’s easier to have logic.

Rack SSL middleware

This gem lets you say:

1
2
3
4
5

# config/application.rb

config.middleware.use Rack::SslEnforcer, :only => /^\/admin\// if Rails.env.production?

This solves the issue of having to specify the protocol in link_to, since it will automatically redirect.

SSL Requirement (in Rails 3)

This version of ssl_requiment claims to work in Rails 3. This is probably the best option right now.

The future

I would like to be able to say something like

1
2
3
4
5
6
7
8
9
10
11
12
13

resources :secrets, :ssl => {:only => [:new, :create]}

resources :secrets, :ssl => :required

resources :secrets, :ssl => :allowed

scope :constraints => [{:protocol => :ssl, :redirect => true}] do

  resources :secrets

end

October 08, 2010