Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails redirect with https

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?

like image 364
Brian D'Astous Avatar asked Nov 02 '09 16:11

Brian D'Astous


People also ask

What is Force_ssl?

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.


2 Answers

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 
like image 71
Olly Avatar answered Oct 06 '22 09:10

Olly


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'] } 
like image 36
Martin Tournoij Avatar answered Oct 06 '22 09:10

Martin Tournoij