DEV Community

Pacharapol Withayasakpunt
Pacharapol Withayasakpunt

Posted on

SSL/HTTPS-ify for Heroku

Heroku already have HTTPS by default. You don't have to buy your own SSL certicate.

But you do have to embed some server-side code to redirect to SSL -- https://help.heroku.com/J2R1S4T8/can-heroku-force-an-application-to-use-ssl-tls

For unsupported platforms, like Node.js-Fastify, you might have to write your own.

The guides are

Reverse Proxies (Heroku, nodejitsu and others)

Heroku, nodejitsu and other hosters often use reverse proxies which offer SSL endpoints but then forward unencrypted HTTP traffic to the website. This makes it difficult to detect if the original request was indeed via HTTPS. Luckily, most reverse proxies set the x-forwarded-proto header flag with the original request scheme. express-sslify is ready for such scenarios, but you have to specifically request the evaluation of this flag:

app.use(enforce.HTTPS({ trustProtoHeader: true }))

Please do not set this flag if you are not behind a proxy that is setting this flag. HTTP headers can be easily spoofed outside of environments that are actively setting/removing the header.

Or

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
Enter fullscreen mode Exit fullscreen mode

So, the Fastify code becomes:- (I modified the code from express-sslify)

    const app = fastify()

    app.addHook('preHandler', async (req, reply) => {
      const isHttps = ((req.headers['x-forwarded-proto'] || '').substring(0, 5) === 'https')
      if (isHttps) {
        return
      }

      const { method, url } = req.req

      if (method && ['GET', 'HEAD'].includes(method)) {
        const host = req.headers.host || req.hostname
        reply.redirect(301, `https://${host}${url}`)
      }
    })
Enter fullscreen mode Exit fullscreen mode

My homepage is currently on Netlify, though; and it don't have to purchase SSL certificate either.

For DigitalOcean, you might use Let's Encrypt.

I believe that the reason to use SSL/TLS, is that HTTP can be intercepted. Not sure how safe it is in localhost. (Of course it is unsafe in 0.0.0.0)

Top comments (0)