Creating an HTTPS Server with Node.js

SSL setup done right

Update: A newer version of this article is now available at What’s that Lambda.

Let’s jump straight into the Node.js part where we will create an HTTPS server on top of Express framework. We will assume that you have Node and NPM installed on your machine.


We start off with installing express. The following command will install express and save it in node_modules folder.

npm i express -g

Once done, we will create a new .js file with (whatever name you wish to give it) name app.js . Now in the file we will add these few lines. Here the require function helps us in including the express module in our file for further usage. An instance of express is created as app. The same goes with fs. fs is an api provided by Node to read/write files from/to directories. We will use fs (file system) to read our SSL certificate files.

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

Now, the most important part of all. Get an SSL certificate. A standard SSL certificate comes with two important files, Primary certificate and Intermediate certificate. To get an SSL, you will have to generate a CSR from your server for validation. Also we need to generate a key (private key) to maintain an HTTPS connection with the server. Running the following command in a linux environment will get us our desired mydomain.csr and private.key files.

openssl req -new -newkey rsa:2048 -nodes -out mydomain.csr -keyout private.key

Use the .csr to generate your certificates and save the generated certificate files (.crt) and the private.key file in a directory in the root (say encryption).

Now we need to read these files and get our HTTPS server started. The following will do the reading and saving the buffer in respective variables. Keep in mind that you read your files with readFileSync function and not readFile. The readFileSync function tends to block the io while a reading file ensuring that all certificate files are read before attempting to create a connection.

var key = fs.readFileSync('encryption/private.key');
var cert = fs.readFileSync( 'encryption/primary.crt' );
var ca = fs.readFileSync( 'encryption/intermediate.crt' );

Once done, we will create an options variable using our certificate files like this,

var options = {
key: key,
cert: cert,
ca: ca
};

and create our server using the options and app (the express instance we created earlier, remember?) which will listen to all connections on port 443 (https’ default port).

var https = require('https');
https.createServer(options, app).listen(443);

Save your file and run

node app.js

If everything was properly followed and certificates were correctly generated for the domain you are using to point to your server, you will see a green https bar on the left of the address bar. However, there’s a catch. We haven’t yet made sure that our HTTP traffic is directed to HTTPS. Let’s do that.

We will create another server which runs along side HTTPS and and will redirect to it.

var http = require('http');
http.createServer(app).listen(80);

This will create an HTTP server listening on port 80 (http’s default port), and now your domain runs on both HTTP and HTTPS web protocol. To force HTTPS using express-force-ssl middleware. The following will install the middleware.

npm i express-force-ssl

and this will create an instance of the middleware for our use.

var forceSsl = require('express-force-ssl');

Let’s configure the middleware with our express installation.

app.use(forceSsl);

That’s it. Express will now know that we wish to direct our HTTP traffic to HTTPS and will transform every http request into an https one.

Note: This will work for smaller projects, more specifically those projects that don’t need faster connection since the server side redirect tends to add delay. For a faster connection such a setup is not recommended. Instead, use NGINX on top of the Node.js server and let it handle the traffic (HTTP and HTTPS, both including the redirect).