I am upgrading an application to Rails 3.0.0 and am wondering if the standard method for adding SSL has changed (I vaguely remember demos indicating the router could now han
After spending an afternoon looking for the best solution I settled on the approach described in this article: http://clearcove.ca/blog/2010/11/how-to-secure-a-rails-app-on-heroku-with-ssl-firesheep/ which referenced this article: Force SSL using ssl_requirement in Rails 2 app
Basically do this:
# lib/middleware/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/application.rb
config.autoload_paths += %W( #{ config.root }/lib/middleware )
# config/environments/production.rb
config.middleware.use "ForceSSL"
Toppic is old but just for googling people:
in *app/controller/your_controller.rb*
class LostPasswordsController < ApplicationController
force_ssl
def index
#....
end
end
if globally use it in application controller
http://apidock.com/rails/ActionController/ForceSSL/ClassMethods/force_ssl
...thx S.L. for tip
In later Rails (at least 3.12+) you can use the following, environment-specific:
in config/environments/production.rb (or other environment)
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true
It's indeed pretty simple in Rails 3. In config/routes.rb
:
MyApplication::Application.routes.draw do
resources :sessions, :constraints => { :protocol => "https" }
end
Or if you need to force SSL for multiple routes:
MyApplication::Application.routes.draw do
scope :constraints => { :protocol => "https" } do
# All your SSL routes.
end
end
And linking to SSL routes can be done like this:
<%= link_to "Logout", sessions_url(:protocol => 'https'), :method => :delete %>
If you wish to automatically redirect some controllers (or actually, some subpaths) to an equivalent https-based URL, you can add something like this to your routes (I wish this part were simpler):
# Redirect /foos and anything starting with /foos/ to https.
match "foos(/*path)", :to => redirect { |_, request|
"https://" + request.host_with_port + request.fullpath }