Enable https for local nodejs

Forge Community Blog

Information. Insights. Code. Connections.

Blog
Enable https for local nodejs

Enable https for local nodejs

March 1, 2017

Some of the services out there require an https Callback URL for 3 legged authentication. In such a case, in order to test your webservice locally you'll need to add https support.

One way to achieve that in case of a nodejs project is to follow these 2 steps:

1) Generate the SSL cerificate and key for localhost

The combination of two of the replies on stackoverflow had pretty much everything needed for both steps. Here is the one for certificate generation in the terminal:

- Generate an SSL certificate for localhost (link)

openssl genrsa -des3 -out server.key 1024

- You need to enter a password here which you need to retype in the following steps
(when asked "Common Name" type in: localhost)

openssl req -new -key server.key -out server.csr

openssl x509 -req -days 1024 -in server.csr -signkey server.key -out server.crt

Also, don't forget the password you used as we'll need it in the next step.

2) Use the https nodejs module to route all resources through https

Originally I had this code:

var app = require('./server/server');

// Start server
var server = app.listen(app.get('port'), function () {
    console.log('Starting at ' + (new Date()).toString());
    console.log('Server listening on port ' + server.address().port);
});

Then I added a reference to https and fs modules in my package.json file and modified the code like this:

var app = require('./server/server');

// Setting up local https support
var fs = require('fs');
var https = require('https');

var options = {
    key: fs.readFileSync('/etc/apache2/ssl/server.key'),
    cert: fs.readFileSync('/etc/apache2/ssl/server.crt'),
    passphrase: '<the password you used for the certificate>',
    requestCert: false,
    rejectUnauthorized: false
};

// Start server
var server = https.createServer(options, app).listen(app.get('port'), function () {
    console.log('Starting at ' + (new Date()).toString());
    console.log('Server listening on port ' + server.address().port);
});

The production version of your webservice will probably go somewhere that supports https by default (e.g. like heroku) so it won't need your self-signed certificate.
In that case, the best thing is to combine the two solutions and switch between them based on the environment:

var app = require('./server/server');

// In case of production environment (e.g. herokuapp) https will
// be provided automatically, otherwise we need to set up the local https
// support using https library and our locally saved key
if (process.env.NODE_ENV === "production") {
  // Start server
  var server = app.listen(app.get('port'), function () {
    console.log('Starting at ' + (new Date()).toString());
    console.log('Server listening on port ' + server.address().port);
  });
} else {
  // Setting up local https support
  var fs = require('fs');
  var https = require('https');

  var options = {
    key: fs.readFileSync('/etc/apache2/ssl/server.key'),
    cert: fs.readFileSync('/etc/apache2/ssl/server.crt'),
    passphrase: '<the password you used for the certificate>',
    requestCert: false,
    rejectUnauthorized: false
  };

  // Start server
  var server = https.createServer(options, app).listen(app.get('port'), function () {
    console.log('Starting at ' + (new Date()).toString());
    console.log('Server listening on port ' + server.address().port);
  });
}

My browsers don't seem too keen on self-signed certificates and cross out the https part, but it's still working fine and good enough for testing:

For an example of the above, have a look at this github project: 
https://github.com/adamenagy/data.management-nodejs-integration.egnyte

Adam Nagy

Adam Nagy joined Autodesk back in 2005 and has been providing programming support, consulting, training and evangelism to external developers. He started his career in Budapest, then worked in Prague for 3 years and now lives in South England, UK.... More