Automatic HTTPS connection/redirect with node.js/express
Ryan, thanks for pointing me in the right direction. I fleshed out your answer (2nd paragraph) a little bit with some code and it works. In this scenario these code snippets are put in my express app:
// set up plain http servervar http = express();// set up a route to redirect http to httpshttp.get('*', function(req, res) { res.redirect('https://' + req.headers.host + req.url); // Or, if you don't want to automatically detect the domain name from the request header, you can hard code it: // res.redirect('https://example.com' + req.url);})// have it listen on 8080http.listen(8080);
The https express server listens ATM on 3000. I set up these iptables rules so that node doesn't have to run as root:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 3000
All together, this works exactly as I wanted it to.
To prevent theft of cookies over HTTP, see this answer (from the comments) or use this code:
const session = require('cookie-session');app.use( session({ secret: "some secret", httpOnly: true, // Don't let browser javascript access cookies. secure: true, // Only use cookies over https. }));
Thanks to this guy:https://www.tonyerwin.com/2014/09/redirecting-http-to-https-with-nodejs.html
If secure, requests via https, otherwise redirects to https
app.enable('trust proxy')app.use((req, res, next) => { req.secure ? next() : res.redirect('https://' + req.headers.host + req.url)})
If you follow conventional ports since HTTP tries port 80 by default and HTTPS tries port 443 by default you can simply have two server's on the same machine: Here's the code:
var https = require('https');var fs = require('fs');var options = { key: fs.readFileSync('./key.pem'), cert: fs.readFileSync('./cert.pem')};https.createServer(options, function (req, res) { res.end('secure!');}).listen(443);// Redirect from http port 80 to httpsvar http = require('http');http.createServer(function (req, res) { res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url }); res.end();}).listen(80);
Test with https:
$ curl https://127.0.0.1 -ksecure!
With http:
$ curl http://127.0.0.1 -iHTTP/1.1 301 Moved PermanentlyLocation: https://127.0.0.1/Date: Sun, 01 Jun 2014 06:15:16 GMTConnection: keep-aliveTransfer-Encoding: chunked
More details : Nodejs HTTP and HTTPS over same port