Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting HTTPS under ExpressJS works only with 1 out of 4 methods

I recently added a SSL certificate to my website. After adding HTTPS support I wanted to redirect people to the secure connection. I googled to see how to detect HTTPS and found on Stack many different ways. It seams they work for others but they don't work for me. Out of 4 ways to check for a secure connection, only one worked.

What doesn't work for me:

  • req.secure: always return false even if i put manually https://
  • req.connection.encrypted: always return undefined even if i put manually https://
  • req.protocol: always return http even if i put manually https://

What works:

req.headers['x-forwarded-proto'] is the only way that actually returns reality.

Knowing this I redirect to a secure connection in the following way:

// Check if the connection is secure, if not, reddiret to a secure one.
function requireHTTPS(req, res, next) {
    if(process.env.NODE_ENV == 'production') {
        if (req.headers['x-forwarded-proto'] !== 'https') {
            return res.redirect('https://' + req.get('host') + req.url);
        }
    }

    next();
}

app.use(requireHTTPS);

In any other way that I mentioned above I would get a redirect loop because even after redirecting to HTTPS, the above methods would return false or http.

My question is: why the other methods don't work?

Tech spec:

  • Website: https://simpe.li
  • Hosted on Heroku
  • Node versions: 4.1.1
  • Express: 4.13.0
like image 936
David Gatti Avatar asked Mar 22 '26 05:03

David Gatti


1 Answers

Heroku exposes HTTPS for you, but then proxies standard HTTP to your worker. The req.headers['x-forwarded-proto'] method is the correct way to detect HTTPS under Heroku. Similarly, you'll need to access the x-forwarded-for and x-forwarded-port if you need the originating IP address and port.

The Heroku Routing documentation has more details on their routing structure.

like image 145
keithmo Avatar answered Mar 23 '26 19:03

keithmo