Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forwarding http to https in node.js express app using EBS & ELB environment

I am using the following to redirect all http requests to https requests.

I can see from logs that the header 'x-forwarded-proto' is never populated and is undefined.

app.get('*', function(req, res, next) {
    //http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#x-forwarded-proto
    if (req.headers['x-forwarded-proto'] != "https") {
        res.redirect('https://' + req.get('host') + req.url);
    } else {
        next();     
    }
});

It is causing a redirect loop. How can I redirect properly without looping?

like image 404
user883499 Avatar asked Sep 27 '13 08:09

user883499


2 Answers

edit: my original answer below is for express 3.x, for 4.x you can get a string http or https in req.protocol, thx @BrandonClark


use req.get, not req.headers. Note that POST requests and all other non-GET will not see this middleware. It's also possible that Express does not carry the x-forwarded-proto header across when you redirect. You may need to set it yourself.

app.get('*', function(req, res, next) {
//http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#x-forwarded-proto
    if (req.get('x-forwarded-proto') != "https") {
        res.set('x-forwarded-proto', 'https');
        res.redirect('https://' + req.get('host') + req.url);
    } else {
        next();     
    }
});

Another way to force https:

function ensureSecure(req, res, next){
  if(req.secure){
    // OK, continue
    return next();
  };
  res.redirect('https://'+req.host+req.url); // handle port numbers if non 443
};

app.all('*', ensureSecure);
like image 120
Plato Avatar answered Nov 01 '22 20:11

Plato


You can edit the nginx config file in the EC2 instance. SSH to ec2 instance and follow the following steps

  1. go to /etc/nginx/conf.d
  2. open 00_elastic_beanstalk_proxy.conf sudo vi 00_elastic_beanstalk_proxy.conf
  3. put

    location / { if ($http_x_forwarded_proto != 'https') { rewrite ^ https://$host$request_uri? permanent; } … }

  4. reload nginx sudo /usr/sbin/nginx -s reload

like image 34
Kamrul Avatar answered Nov 01 '22 20:11

Kamrul