If your Express-powered Node app sends user information over the wire it’s recommended to use a secure connection. Because of this you might want to force all your requests to run over https, even when someone explicitly opens your app using http. Luckily this is pretty easy using a Express middleware function.

server.use('/path', function(req, res, next) {
    if(!req.secure) {
      var secureUrl = "https://" + req.headers['host'] + req.url;
      res.writeHead(301, { "Location":  secureUrl });
      res.end();
    }
    next();
  });
  

If the current protocol is not https, the function stops the request-response cycle and returns a 301 response that redirects to the secure version of the current url. If the current url is secure, the function calls next() to pass control to the next middleware. Without this the app will be left hanging.

When you want to mount a middleware for every request, you can ommit the first argument:

server.use(function(req, res, next) {
   ...
  });
  

When working locally, your server may not have a SSL certificate installed. I think it’s a good idea to add a environment conditional too.

if(!req.secure && process.env.NODE_ENV === 'production') {
  ...
  }
  

Middleware functions are executed sequentially, therefore the order of middleware inclusion is important. Make sure your HTTPS middleware function is included before all the other middleware functions and routes.

Update: If you use a DNS redirect, req.secure may not work correctly and cause an infinite redirect loop. You should use req.headers['x-forwarded-proto'] !== 'https' instead in this case.

Leave a Reply