Ayan Ray

Thoughts on Software Engineering

Adding HTTPS (SSL) to Express 4.X Applications

Anytime it takes me more than 2-3 sources to figure out how to do something simple, something is wrong. This post was created because I had some issues setting up Express with SSL. Generally, the process is simple as all you need to do is generate or purchase a certificate and reference it in express to get a secure connection.

EDITED [Jan 16, 2016] – Added an example GitHub Repo for a working example. Good luck everyone!

Why use HTTPS on your website anyway?

The biggest reason is that without HTTPS, your data is being transferred in clear text over the Internet without any encryption (for public websites). So if you go to an HTTP only website, type in your password and hit submit, you send a message to the server where your password is visible in clear text. It’s very easy to capture this using tools like Wireshark and even easier if you are just using Wireless in a coffee shop (and yes, even if it’s WPA2).

To prevent this, we all should use application level encryption. Thankfully, it is easy to add encryption to HTTP using the secure sockets layer (SSL). If you want your users to be protected against attackers signing in as them, using their credentials for other websites, you must use HTTPS. Even for a site just in development, you should set this up as it’s important to set the bar high right from the beginning. It does add latency as there’s extra steps in the protocol, and in some cases you can decide to not use SSL, but generally for any page you send private data (a user’s password for example), you should use SSL.

Setting up SSL on Express 4.0 (4.X)

First of all, you need a certificate. Either you can purchase this online from a certificate authority (CA) like VeriSign or your hosting provider. For your development setup, you can generate your own certificate.
Here’s the code to generate one on your local machine but there are also numerous guides on the Internet, some more verbose than others (I.e. Heroku).
openssl genrsa 1024 > private.key
openssl req -new -key private.key -out cert.csr
openssl x509 -req -in cert.csr -signkey private.key -out certificate.pem

The first line generates a private RSA key. The second line creates a certificate request. And the last one generates the actual certificate. Note, there are no paths in these files, so you can move them wherever you want. And you really only need the private.key and certificate.pem.

Now, we need to reference the certificate and private key in Express.
var https = require(‘https’);
var httpsPort = 3443;
// Setup HTTPS
var options = {
  key: fs.readFileSync(‘path/to/private.key’),
  cert: fs.readFileSync(‘path/to/certificate.pem’)
};
var secureServer = https.createServer(options, app).listen(httpsPort);
Note that I had something else listening on the standard SSL port (443) so I chose something similar (3443) since my default express HTTP port is 3000.
Now if you restart express and go visit https://yoursite.com, you’ll see that there’s either a warning that this site is not actually secure (if you used the dev setup) or if you used a certificate from a valid CA, it will simply load your site. This is more complicated to explain how it works, but leave a comment and I can discuss it.

How to redirect all HTTP traffic to HTTPS in Express?

This is a fairly simple thanks to express routing.
var app = express();
app.set(‘port_https’, 3443); // make sure to use the same port as above, or better yet, use the same variable
// Secure traffic only
app.all(‘*’, function(req, res, next){
  if (req.secure) {
    return next();
  };
 res.redirect(‘https://’+req.hostname+”:”+app.get(‘port_https’)+req.url);
});

Git Repo with Completed Working Example

https://github.com/ayanray/express4_SSL_example

All done! Hope this is useful!

Leave a comment if you need any clarification.

« »

© 2017 Ayan Ray. Theme by Anders Norén.