20

I have a Rails application which need to run under SSL. I tried ssl_requirement but seems I have to type in all the actions in every controllers.

Is there any method that I can add a before_filter in application controller with ssl_requirement, so that the apps will redirect to https automatically when user request is in http?

Thanks all. :)

lulalala
  • 15,996
  • 12
  • 101
  • 165
Victor Lam
  • 3,446
  • 8
  • 29
  • 42

3 Answers3

32

Use a Rack Middleware.

# lib/force_ssl.rb
class ForceSSL
  def initialize(app)
    @app = app
  end

  def call(env)
    if env['HTTPS'] == 'on' || env['HTTP_X_FORWARDED_PROTO'] == 'https'
      @app.call(env)
    else
      req = Rack::Request.new(env)
      [301, { "Location" => req.url.gsub(/^http:/, "https:") }, []]
    end
  end
end

# config/environment.rb
config.middleware.use "ForceSSL"
Simone Carletti
  • 164,184
  • 42
  • 341
  • 356
  • 2
    `lib/force_ssl.rb` won't be included by default in Rails 3.0.X. You'll need to add this line to your `application.rb`: `require File.expand_path('../../lib/force_ssl.rb', __FILE__)` or do some sort of similar `require` elsewhere. Also, the `config.middleware.use "ForceSSL"` line should go in `config/environments/production.rb`. – Max Masnick Jun 22 '11 at 17:34
  • 6
    As pointed out by Simone Carletti, in rails >= 3.1 there a force_ssl method available. See http://www.simonecarletti.com/blog/2011/05/configuring-rails-3-https-ssl/ – Enrico Carlesso Jul 11 '11 at 16:10
  • Thank buddies for keep updating. :) – Victor Lam Oct 07 '11 at 03:14
5

You can try test if request is in ssl or not in a before_filter in your application

class Application < AC::Base

  before_filter :need_ssl

  def need_ssl
    redirect_to "https://#{request.host}/#{request.query_string}" unless request.ssl?
  end
end
Community
  • 1
  • 1
shingara
  • 44,790
  • 11
  • 96
  • 104
1

The key problem is that force_ssl.rb isn't being loaded and that lib isn't loaded by default in rails 3.1. You have to add

config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]

to application.rb