SSL/HTTPS server with Node.js and Express.js

Posted by Kyriakos Chatzidimitriou on 2014-10-15

So let’s assume the requirement is to create an https server that will redirect traffic to https if http is used in a request to the server instead. I created this little guide by bundling together a couple of links related to the subject.

We will begin by creating quickly a project using the express-generator:

$ express https-server
$ cd https-server && npm install
$ npm start

Server should be running at http://localhost:3000/. Now let’s create the certificates (Reference):

$ openssl genrsa 1024 > file.pem
$ openssl req -new -key file.pem -out csr.pem
$ openssl x509 -req -days 365 -in csr.pem -signkey file.pem -out file.crt

We assumed no passphrase was used. We can then read the certificates in the starting point file www:

var fs = require("fs");
var config     = {
    key: fs.readFileSync('file.pem'),
    cert: fs.readFileSync('file.crt')
};

The next step is to create two servers, one to listen on http and port 3000 and one on https and port 8000 (Reference). The www file becomes:

#!/usr/bin/env node
var debug = require('debug')('https-server');
var app = require('../app');
var https = require('https');
var http = require('http');
var fs = require("fs");
var config = {
    key: fs.readFileSync('file.pem'),
    cert: fs.readFileSync('file.crt')
};

http.createServer(app).listen(3000)
https.createServer(config, app).listen(8000)

Now one can navigate both to http://localhost:3000 and https://localhost:8000 and get the same response. In the latter case with the usual “proceed with caution” notice since the certificate is not signed by a trusted authority.

The last step is to redirect traffic that come into http to https by using a middleware for all routes (Reference):

function ensureSecure(req, res, next){
  if(req.secure){
    return next();
  };
  res.redirect('https://'+req.host+':' + 8000 + req.url);
};

app.all('*', ensureSecure);

app.use('/', routes);
app.use('/users', users);

So http://localhost:3000 and http://localhost:3000/users redirect to https://localhost:8000 and https://localhost:8000/users respectively.

The complete code can be found in github.

Last but not least, in production you can redirect traffic to standard http and https ports like in this reference.


comments powered by Disqus