Force my heroku app to use SSL (https)
I just use the "Always use HTTPS"-Feature from Cloudflare for that. Just follow these steps:
1. Sign Up on Cloudflare if you haven't already
2. Add your site example.com
3. Select a plan. (Free plan is enough for that)
4. Review your DNS records. Cloudflare tries to automatically detect the records if you have already some entries at Namecheap for example. Whats important is that you leave at least the Type A record with the IPv4
address and also the CNAME
Type where the Content
is the DNS Target
from the Domain Name in the Heroku Settings of your App. See also the screenshot
5. You need to point Cloudflare's nameservers to activate your site successfully otherwise Cloudflare is unable to manage your DNS and optimize your site. Remove existing nameservers and then replace them with Cloudflare's nameservers. They will show you also the instructions on a page (Could take up to 48h until your site is active, but in my experience it took only 15mins). See the screenshot with Namecheap as example:
6. Go to the SSL/TLS
Section and under the section Edge Certificates
enable the "Always Use HTTPS"-Feature. Now all requests with scheme "http" should be redirected to "https"
Bonus 1: To forward also requests without the scheme or www for example if the user enters just example.com
or www.example.com
just create a page rule to forward these requests to your secured url. For that go to the section "Page Rules" and hit the "Create Page Rule"-Button. Enter the url which should match and add the Setting Forwarding URL
with the status code 301 - Permanent Redirect
. Enter also the destination url as follows with $1
at the end to make it work correctly. Hit "Save and Deploy" and you're ready to go. For more details check the section "Advanced forwarding options" here (Keep in mind that you may need to clear your cache to see the changes). See the screenshot:
Bonus 2: You bought another domain and just want to redirect this to your secured main domain. For example you bought fiveexample.com
and 5example.com
and you want to redirect 5example.com
always to https://www.fiveexample.com
no matter what the user enters regarding 5example.com
e.g. www.5example.com
, http://5example.com
and even https://www.5example.com
even if your second domain has no ssl. Cloudflares page rules are also here a solution. Just follow the steps 1-5 (but at step 4 you don't need the heroku dns target) for your second domain. After you followed the steps to support all forwardings add these three page rules for your second domain. Works also perfectly for .app
domains (Keep in mind that you may need to clear your cache to see the changes). See screenshot
For anybody coming along to this post, I was having this problem and discovered that I had code in this order, which was screwing things up:
### old way
app.use(express.static('build'));
app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
res.redirect(`https://${req.header('host')}${req.url}`)
} else {
next();
}
});
### new way (just swap the order)
app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
res.redirect(`https://${req.header('host')}${req.url}`)
} else {
next();
}
});
app.use(express.static('build'));
Once I moved the express.static('build') below that send app.use method everything worked!
On Heroku, it's slightly tricky to determine the fact that the request came in over http. https is handled at a heroku routing layer and it passes along the request to the node app on http).
This post got me unstuck http://jaketrent.com/post/https-redirect-node-heroku/
There's also NPM module heroku-ssl-redirect helping you to deal with it