I'm maintaining a Ruby on Rails site and I'm confused as to how to perform redirects to relative URLs using the https protocol.
I can successfully create a redirect to a relative URL using http, for example:
redirect_to "/some_directory/"
But I cannot discern how to create a redirect to a URL using the https protocol. I have only been able to do so by using absolute URLS, for example:
redirect_to "https://mysite.com/some_directory/"
I would like to keep my code clean, and using relative URLs seems like a good idea. Does anyone know how to achieve this in Rails?
force_ssl = true , and is passed the options set in config. ssl_options . It does three jobs to enforce secure HTTP requests: TLS redirect: Permanently redirects http:// requests to https:// with the same URL host, path, etc.
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'] }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With