Rails - How to Redirect from http://example.com to https://www.example.com
Solution 1
DNS records cannot define the protocol for a domain, therefore you can't redirect http://
to https://
through DNS. Doing it through the web server configuration is not portable, hard to do, error prone and just plain outdated. This is a job best handled by the Rails router.
# beginning of routes.rb
match "*path" => redirect("https://www.mysite.com/%{path}"), :constraints => { :protocol => "http://" }
match "*path" => redirect("https://www.mysite.com/%{path}"), :constraints => { :subdomain => "" }
Solution 2
As an extension to user2100689's answer, in Rails 3+ you can use config.force_ssl = true
in config/environments/production.rb
The line can just be uncommented as follows
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true
Solution 3
Rails 3.1.0 and higher has force_ssl
, which is a controller method that will redirect to https for non-development environments.
http://api.rubyonrails.org/classes/ActionController/ForceSSL/ClassMethods.html
Place it in each controller that you want to redirect, or better yet, place it in your ApplicationController:
app/controllers/application.rb:
class ApplicationController < ActionController::Base
# ...
force_ssl
# ...
end
This is a good thing to always include in your apps (and of course you'll have to get a certificate). HTTPS Everywhere!
Solution 4
You can always throw this in your production.rb... config.use_ssl = true
Solution 5
Because this is Heroku, you cannot use apache or nginx configs. What you can do is put a before_filter in your ApplicationController, assuming you have 3 or more controllers like these below, although of course they will be in separate files
class ApplicationController < ActionController::Base
def redirect_https
redirect_to :protocol => "https://" unless request.ssl?
return true
end
before_filter :redirect_https
end
class TypicalController < ApplicationController
def blah
end
end
class HomePageController < ApplicationController
skip_before_filter :redirect_https
end
You may also need to fiddle your routes a bit when using devise, but I suspect that was just the way we did it so I won't get into those details here, and I've modified the code above to avoid that complication.
happy hacking.
AnApprentice
working on Matter, a new way to gather professional feedback.
Updated on February 08, 2020Comments
-
AnApprentice about 4 years
I'm looking to learn how to cleanup my app's URLs. My app is powered by Rails 3 on Heroku.
The desired URL is
https://www.example.comite.com
I'd like to redirect all URLs unlike the above to that URL. Is this a Rails thing or DNS?
Bad URLs:
https://example.comite.com http://www.example.comite.com http://example.comite.com
And if anything is trailing, like
http://www.example.comite.com/photo/1
for the url to be redirected with the path:https://www.example.comite.com/photo/1
-
theandym over 13 yearsHe's using Heroku and has no access to the web server config like that.
-
fearless_fool over 12 yearsThis feels like the right way to go, but doesn't answer one key point: how do you transition from
http://mysite.com
tohttps://www.mysite.com
? (Answer the essentially identical question in stackoverflow.com/questions/9027916/… and get double points!) -
Mindey I. almost 12 yearsThis works, but do you need to leave the A records in place? I was assuming you'd be able to redirect
mysite.com
tohttp://www.mysite.com
via DNS, and then once it hit your rails app it would redirect to https using your route contraints. However, with my DNS redirecthttp://mysite.com
redirects as expected, buthttps://mysite.com
doesn't (and never hits my rails server for the route contraints to take effect). I've reverted back to having A records for now, but was just wondering if you knew why the DNS redirect didn't work forhttps://mysite.com
. -
edgerunner almost 12 yearsthere's nothing you can do on the DNS side. As I said, DNS has nothing to do with the protocol. You can redirect a name to another, but not the protocol. It isn't even transmitted to the DNS server. Your browser asks the IP address of
mysite.com
nothttp://mysite.com
, and it gets a reply likeREDIRECT www.mysite.com
notREDIRECT http://www.mysite.com
-
stephenmurdoch over 10 yearsDoes this protect against SSL stripping?
-
Robin Daugherty over 10 yearsI believe this does protect against sslstrip-type attacks. Rails will refuse to serve non-SSL requests by always redirecting to the corresponding HTTPS URL. If sslstrip changes the protocol of the redirect, Rails will simply redirect to HTTPS again.
-
stephenmurdoch over 10 yearsThanks @Robin_Daughtery
-
Simon B. about 7 years@RobinDaugherty CAREFUL, if there is a MITM attack then session cookies will be leaked before the redirect back to https happens. Which means a more advanced sslstrip will pwn your site, and make public wifi's (and spoofed wifis) very dangerous while using your app. To prevent cookies leaking, you need to enable config.use_ssl = true
-
Robin Daugherty about 7 years
force_ssl
is the setting that enables secure cookies. I can find no reference to ause_ssl
setting in the Rails codebase, nor in Google. -
Robin Daugherty about 7 yearsWith Rails 5 (and possibly older versions as well),
use_ssl
will do nothing.force_ssl
is the option that must be set. -
Shrinivas over 6 yearsI am not able to redirect from "example.com" to "example.com" by adding above rules in routes
-
edgerunner over 4 years@Shrinivas they probably won't work unless you put them at the beginning of your
routes.rb