Question:
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.
1 2 3 4 5 6 7 8 9 |
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?
Answer:
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.
1 2 3 4 5 6 7 8 9 10 |
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:
1 2 3 4 5 6 7 8 9 10 |
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); |