Search code examples
node.jshttpssubdomain

Why does HTTP -> HTTPS redirect fail in nodejs when no subdomain is specified?


I'm running a nodejs webapp on Heroku and I want to redirect all users that access via http to https with the corresponding URL.

I have it mostly working however the user is redirected to the home page if no subdomain is specified. Any idea what is going on here?

The node rerouting middleware:

app.enable('trust proxy');
  app.use((req, res, next) => {
    if (req.get('X-Forwarded-Proto') !== 'https') {
      res.redirect(`https://${req.headers.host + req.url}`);
    } else {
      next();
    }
  });

Works: http://www.example.com/page redirects to https://www.example.com/page

Fails: http://example.com/page redirects to https://www.example.com


Solution

  • Because req.url is an inherited property from Node.JS's http module and does not necessarily contain the original URL. Express.JS documentation also states it, https://expressjs.com/en/api.html#req.originalUrl

    If you want to retain the original url you should use the correct property, which is originalUrl.

    app.enable('trust proxy');
      app.use((req, res, next) => {
        if (req.get('X-Forwarded-Proto') !== 'https') {
          res.redirect(`https://${req.headers.host + req.originalUrl}`);
        } else {
          next();
        }
      });