Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to redirect to HTTPS with .htaccess on Heroku Cedar stack

I'm new to cloud hosting...

I'm working on a PHP web app that's hosted on Heroku as a "Cedar" app. Heroku offers "piggy back" SSL to all their subdomains, so I can load https://myapp.herokuapp.com just fine. But I can also load http://myapp.herokuapp.com. I want to force SSL by redirecting http requests to https.

Normally, this would be easy. I would just use mod_rewrite as follows:

RewriteCond %{HTTPS} != on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

BUT THIS DOESNT WORK ON HEROKU!

It appears that SSL terminates upstream, before the traffic ever hits my app. So the %{HTTPS} condition is never met, and the result is a redirect loop. I've also tried the following, which also didn't work:

RewriteCond %{SERVER_PORT} != 443 #<--also redirect loop
RewriteCond %{REQUEST_SCHEME} !https #<--also redirect loop

So my question is how can I detect/redirect-to HTTPS when it's terminated upstream?

like image 357
emersonthis Avatar asked Oct 21 '14 14:10

emersonthis


2 Answers

After spending all day on this, I figured it out!!

The issue is eloquently summarized here.

Bottom line: Heroku sets its own custom header to indicate the ORIGINAL scheme of the traffic (before SSL terminated at the load balancer).

So THIS works in an .htaccess file on Heroku

##Force SSL 

#Normal way (in case you need to deploy to NON-heroku)
RewriteCond %{HTTPS} !=on

#Heroku way
RewriteCond %{HTTP:X-Forwarded-Proto} !https 

#If neither above conditions are met, redirect to https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

The secret sauce is the line with HTTP:X-Forwarded-Proto.

Hope this helps someone else having the same issues! At the time of writing this there is ZERO documentation on this.

like image 190
emersonthis Avatar answered Nov 19 '22 14:11

emersonthis


I added one line to the great answer given above so it doesn't break my local dev environment which doesn't have SSL configured:

# If header is present in the request
RewriteCond %{HTTP:X-Forwarded-Proto} .

(Note RewriteRule is applied only if all preceeding RewriteCond's hold).

like image 39
mwal Avatar answered Nov 19 '22 13:11

mwal