Rails redirect with https

The ActionController::Base#redirect_to method takes an options hash, one of the parameters of which is :protocol which allows you to call:

redirect_to :protocol => 'https://', 
            :controller => 'some_controller', 
            :action => 'index'

See the definition for #redirect_to and #url_for for more info on the options.


Alternatively, and especially if SSL is to be used for all your controller actions, you could take a more declarative approach using a before_filter. In ApplicationController you could define the following method:

def redirect_to_https
    redirect_to :protocol => "https://" unless (request.ssl? || request.local?)
end

You can then add filters in your those controllers which have actions requiring SSL, e.g:

class YourController
    before_filter :redirect_to_https, :only => ["index", "show"]
end

Or, if you require SSL across your entire app, declare the filter in ApplicationController:

class ApplicationController
    before_filter :redirect_to_https
end

If you want your entire application to be served over https then since Rails 4.0 the best way to do this is to enable force_ssl in the configuration file like so:

# config/environments/production.rb
Rails.application.configure do
  # [..]

  # Force all access to the app over SSL, use Strict-Transport-Security,
  # and use secure cookies.
  config.force_ssl = true
end

By default this option is already present in config/environments/production.rb in in newly generated apps, but is commented out.

As the comment says, this will not just redirect to https, but also sets the Strict-Transport-Security header (HSTS) and makes sure that the secure flag is set on all cookies. Both measures increase the security of your application without significant drawbacks. It uses ActionDispatch:SSL.

The HSTS expire settings are set to a year by default and doesn't include subdomains, which is probably fine for most applications. You can configure this with the hsts option:

config.hsts = {
  expires: 1.month.to_i,
  subdomains: false,
}

If you're running Rails 3 (>=3.1) or don't want to use https for the entire application, then you can use the force_ssl method in a controller:

class SecureController < ApplicationController
  force_ssl
end

That's all. You can set it per controller, or in your ApplicationController. You can force https conditionally using the familiar if or unless options; for example:

# Only when we're not in development or tests
force_ssl unless: -> { Rails.env.in? ['development', 'test'] }