bretth18
bretth18

Reputation: 53

Enabling HTTPS on an express server

I'm trying to configure my express server to use HTTPS but I am running into some issues. I followed the documentation to setup my HTTPS server but I am still encountering some errors.

Here's my app.js

var express = require('express');
var app = express();
var server = require('https').createServer(options, app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
var fs = require('fs');

var options = {
  key: fs.readFileSync('/test/key.pem'),
  cert: fs.readFileSync('/test/cert.pem')
};

server.listen(port, function () {
  console.log('Server listening at port %d', port);
});

When starting my server I encounter

https.js:32 if (process.features.tls_npn && !opts.NPNProtocols) { ^ TypeError: Cannot read property 'NPNProtocols' of undefined at new Server (https.js:32:40) at Object.exports.createServer (https.js:56:10)

So, I tried to define NPNProtocols within options, but that did not work. Anyone have any pointers here? Thank you.

Upvotes: 0

Views: 1467

Answers (2)

MoMo
MoMo

Reputation: 480

IMO, the issue is not with the extension of the keys, rather the ssl configuration used. Use https node module with correct ssl options for ca, cert, and key to enable https with express.

// server/index.js
const express = require('express');
const fse = require('fs-extra');
const helmet = require('helmet');
const https = require('https');
const path = require('path');

// path to cert files
const paths = {
  certFile: '/path/to/cert.pem',
  chainFile: '/path/to/fullchain.pem',
  privateFile: '/path/to/privkey.pem',
};

/* Express implementation (ignore) */
const app = express();
app.use(helmet());
app.use(express.static(path.join(__dirname, '..')));
app.get('/', (request, response) => {
  response.sendFile(path.join('index.html'));
});

// setup https
const setupHttps = () => {
  const promises = [
    fse.readFile(paths.chainFile),
    fse.readFile(paths.privateFile),
    fse.readFile(paths.certFile),
  ];

  return Promise
    .all(promises)
    .then(data => {
      const [ chainData, privateData, certData ] = data;
      const options = {
        ca: chainData.toString('utf-8'),
        cert: certData.toString('utf-8'),
        key: privateData.toString('utf-8'),
      };
      return https.createServer(
        options,
        app
      ).listen(443);
    })
    .catch(err => console.log(err));
};

return setupHttps();

EDIT: I used helmetjs for better security with http headers.

Upvotes: 1

Shubham
Shubham

Reputation: 1793

try this once, i think you should have certificate in .crt format. and you will require tls module.

var sslOptions = {
        key: fs.readFileSync('public/server.key'),
        cert: fs.readFileSync('public/server.crt')
};
tls.createServer(sslOptions, function (cleartextStream) {
    var cleartextRequest = net.connect({
        port: port,
        host: serverStr
    }, function () {
        cleartextStream.pipe(cleartextRequest);
        cleartextRequest.pipe(cleartextStream);
    });
}).listen(443);

port is you http port . and sercerStr is you server address.

Upvotes: 1

Related Questions