Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expressjs redirecting to https (using Cloudflare Flexible SSL)

im using Expressjs (NodeJS framework) and I want to redirect all traffic to https, im not using SSL certificates but Cloudflare flexible ssl.

Im using this middleware:

//FORCE SSL
app.use(function(req, res, next) {
  if(!req.secure) {
    return res.redirect(['https://', req.get('Host'), req.url].join(''));
  }
  next();
});

And im launching the app this way:

//Firing Up express
//====================================================================
app.set('port', process.env.PORT || 80);
var server = app.listen(app.get('port'), function() {
   console.log('[-]');
   console.log(('[+] Express server listening on port '+ server.address().port).green);
   console.log('[-]');
});

The application redirects to https:// but then fail to load

Google Chrome console says:

Failed to load resource: net::ERR_CONNECTION_REFUSED https://beta.domain.io/
Failed to load resource: net::ERR_CONNECTION_CLOSED https://beta.domain.io/
Failed to load resource: net::ERR_CACHE_MISS 

Can someone point me in the right direction?

Thanks in advance.

like image 979
mdv Avatar asked May 19 '26 04:05

mdv


1 Answers

CloudFlare's server is actually talking to your server via unsecured http. It then forwards the response on to the client via https. Since all connections to your server are http, your app redirects everything. In that case, there is never a valid response and therefore fails to load.

When a proxy server is connecting to your web server they pass additional information about the client connection via http headers. There are two headers you should be looking for. X-Forwarded-For and X-Forwarded-Proto. X-Forwarded-For would tell you what the originating client's IP address is and X-Forwarded-Proto tells you what protocol the originating client is using.

In your case, you want to look at the X-Forwarded-Proto header and if it is http then redirect to the equivalent https resource.

//FORCE SSL
app.use(function(req, res, next) {
  if(req.headers['x-forwarded-proto']==='http') {
    return res.redirect('https://' + req.headers.host + req.url);
  }
  next();
});
like image 61
Daniel Avatar answered May 20 '26 17:05

Daniel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!