Force SSL with expressjs 3
Asked Answered
A

3

28

I'm running a node.js express 3 server with no proxies and using SSL.

I'm trying to figure out how to force all connections to go through https.

Google searching shows me this:

https://groups.google.com/forum/#!topic/express-js/Bm6yozgoDSY

There's currently no way to force https redirects, though that seems like a bit of a strange work-around. We have an https-only app and we just have a simple ~4 line node http server that redirects, nothing fancy

Which is what I need, but he doesn't say what those 4 lines are.

How do we do this? Thanks.

Attitude answered 22/5, 2012 at 7:32 Comment(0)
K
86

I don't really understand the point in starting two servers when only one can do the job perfectly. For example, by adding a simple middleware in your server file:

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

This will redirect any non-secure request to the corresponding HTTPS page. For example, http://example.com/ to https://example.com/ and http://example.com/foo?bar=woo to https://example.com/foo?bar=woo. This is definitely the behavior I would expect. Maybe you should filter this by host, so it redirects only on domains for which you own and installed a proper certificate.

If your app is running behind another server like Nginx, you may want to add the configuration parameter app.set('trust proxy', true). Or, even better, make Nginx do the redirect itself, which will be more efficient than any Node.js app.

Edit: According to my benchmarks, join is a little faster than + for concatenating strings. Nothing dramatic, but every win is a win...

Keek answered 23/5, 2012 at 8:1 Comment(7)
I tried it and it seems like you still need to create a http server in order for this to work, basically 2 servers. Which is fine, and this answer works.Attitude
True. I meant two different pieces of code, sorry for the confusion. Or, only one app with some proxy server / load balancer =)Keek
@prx The edit you suggested was rejected because it should be posted as a new answer rather than an edit to an existing answer.Helpful
For anyone using a newer version of Express (4.x) you will need to update the redirect to use baseUrl instead of url. The line should read: return res.redirect(['https://', req.get('Host'), req.baseUrl].join(''));Sassy
@Keek this is working fine except for one case i.e. for the first time a computer loads the url without any prefix example "portal.abcd.xyz", in this case it loads portal.abcd.xyz if we reload the page it redirects to httpsCrites
I don't understand the issue here. Do you have a clear case (as a new question maybe) I could look into? The prefix is merely a representation of the protocol ; it is never transferred to the server per se.Keek
@Keek I'm seeing ERR_TOO_MANY_REDIRECTSJaejaeger
P
0

You should create a second server listening on 80 and redirect with a 301 header to your https server:

var express = require('express');
var app = express();

app.get('/', function(req, res, next){
  res.redirect('https://' + app.address().address)
});

app.listen(80);
Parley answered 22/5, 2012 at 9:43 Comment(2)
that would redirect all traffic, even existing https ones?Attitude
This can definitely work, but this approach doesn't work if the user requests another page that "/". In this case, he'll just get a disturbing 404 error.Keek
L
0

I had a similar problem and the redirect solution is not suitable for me because essentially I want to get rid of the browser's insecure warning,

So instead of redirect every message, I did:

app1 = new express()
app1.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/redirect.html'));

}); app1.listen(80, function(){'redirect server running on 80 port'})

and in the redirect.html is just a redirecting html file:

<meta http-equiv="refresh" content="0; URL='https://my-site.com'" />

Of course, this won't work for complicated cases when you want to redirect all routings, but for me, I only want to redirect my homepage to my https homepage and get rid of the browser's insecure warning. Hope this help somebody!

Landau answered 17/3, 2019 at 23:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.