165

Before, in an older version of express, I could do this:

express.createServer({key:'keyFile', cert:'certFile'});

However, in newer versions of express this no longer works:

var app = express();

Should I call app.use() to set the certs? If so how?

Patches
  • 176
  • 7
murvinlai
  • 48,919
  • 52
  • 129
  • 177

3 Answers3

201

See the Express docs as well as the Node docs for https.createServer (which is what express recommends to use):

var privateKey = fs.readFileSync( 'privatekey.pem' );
var certificate = fs.readFileSync( 'certificate.pem' );

https.createServer({
    key: privateKey,
    cert: certificate
}, app).listen(port);

Other options for createServer are at: http://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
ebohlman
  • 14,795
  • 5
  • 33
  • 35
  • 1
    Hmmm from node: https.createServer(options, [requestListener]) so passing app is ok? isn't that app is an 'object'... – murvinlai Aug 05 '12 at 04:46
  • 1
    what is the function signature for 'app'? i try to look up on github for express but i don't see that it takes (req, res) – murvinlai Aug 05 '12 at 04:47
  • 3
    Take a look at the definition of `createServer` in `connect.js` (express just inherits this from connect). You'll see that it returns a function with the correct signature. `connect()` is simply an alias for `connect.createServer()` and therefore so is `express()` (which probably does some extra initialization, but the result is still a function appropriate for use as a request handler). – ebohlman Aug 06 '12 at 01:08
  • 1
    -1, what library? Explanation as to what `app` is? Pasting a single line of code isn't concise *or* clear. – Qix - MONICA WAS MISTREATED May 01 '14 at 01:54
  • 12
    @Qix - in the OPs example, `app` is defined. This answer is satisfactory. – Seiyria May 19 '14 at 14:08
  • I've added some useful links to official docs for the answer, for my own reference as well as yours. – mikemaccana Dec 17 '14 at 17:30
  • 1
    app is what is return by this in Node.js - require('express')() – Alexander Mills Oct 28 '15 at 20:30
  • 7
    is there any outline how to obtain the .pem files? I have two .crt files from my cert provider. – SCBuergel Aug 10 '16 at 09:52
  • I was successful using key and crt files (instead of pem). I got them via the process described here: https://alexanderzeitler.com/articles/Fixing-Chrome-missing_subjectAltName-selfsigned-cert-openssl/ , but I had to s/-config <( cat server.csr.cnf )/-config server.csr.cnf/ and then bumble about a while to figure out how to add my root certificate (which was a PEM file) to my list of trusted providers. Of course, if you are using a signed certificate from a common authority, you won't need to do any of this. Main point is that the server works with key/crt files as well as pem. – Joshua Richardson Jan 01 '21 at 21:43
128

I was able to get SSL working with the following boilerplate code:

var fs = require('fs'),
    http = require('http'),
    https = require('https'),
    express = require('express');

var port = 8000;

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

var app = express();

var server = https.createServer(options, app).listen(port, function(){
  console.log("Express server listening on port " + port);
});

app.get('/', function (req, res) {
    res.writeHead(200);
    res.end("hello world\n");
});
geoffreak
  • 2,288
  • 3
  • 17
  • 18
  • 2
    How do you actually see the hello world on the browser? https://127.0.0.1:8000/ gives me a Error 107 (net::ERR_SSL_PROTOCOL_ERROR): SSL protocol error. – aCuria Nov 18 '12 at 10:27
  • 1
    upvoted too soon. I get -- Error: addListener only takes instances of Function – Meekohi Mar 20 '13 at 15:03
  • 1
    keep in mind that was written quite a while ago. It is possible this no longer works in newer versions of Express or Node.js – geoffreak Mar 21 '13 at 14:36
  • 12
    This is years too late, but the SSL_PROTOCOL_ERROR can be caused by the fact that you're using http://. It should be https:// – andreimarinescu Sep 14 '16 at 10:56
14

This is my working code for express 4.0.

express 4.0 is very different from 3.0 and others.

4.0 you have /bin/www file, which you are going to add https here.

"npm start" is standard way you start express 4.0 server.

readFileSync() function should use __dirname get current directory

while require() use ./ refer to current directory.

First you put private.key and public.cert file under /bin folder, It is same folder as WWW file.

no such directory found error:

  key: fs.readFileSync('../private.key'),

  cert: fs.readFileSync('../public.cert')

error, no such directory found

  key: fs.readFileSync('./private.key'),

  cert: fs.readFileSync('./public.cert')

Working code should be

key: fs.readFileSync(__dirname + '/private.key', 'utf8'),

cert: fs.readFileSync(__dirname + '/public.cert', 'utf8')

Complete https code is:

const https = require('https');
const fs = require('fs');

// readFileSync function must use __dirname get current directory
// require use ./ refer to current directory.

const options = {
   key: fs.readFileSync(__dirname + '/private.key', 'utf8'),
  cert: fs.readFileSync(__dirname + '/public.cert', 'utf8')
};


 // Create HTTPs server.

 var server = https.createServer(options, app);
hoogw
  • 4,982
  • 1
  • 37
  • 33
  • How would this work with a web-server-1 and web-server-2 with 1 load balancer? The SSL cert is stored on the load balaner, which means the path to the certs does not work? – ii iml0sto1 Jan 23 '23 at 20:03
  • 1
    If you have a load balancer, then it should terminate the TLS (as it holds the certificates). At that point, you just need to serve yo a normal http app, with no concerns of SSL @iiiml0sto1 – Samarth Ramesh Aug 03 '23 at 20:14