[javascript] How to create an HTTPS server in Node.js?

Given an SSL key and certificate, how does one create an HTTPS service?

This question is related to javascript node.js ssl https webserver

The answer is


To enable your app to listen for both http and https on ports 80 and 443 respectively, do the following

Create an express app:

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

The app returned by express() is a JavaScript function. It can be be passed to Node’s HTTP servers as a callback to handle requests. This makes it easy to provide both HTTP and HTTPS versions of your app using the same code base.

You can do so as follows:

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

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

http.createServer(app).listen(80);
https.createServer(options, app).listen(443);

For complete detail see the doc


  1. Download rar file for openssl set up from here: https://indy.fulgan.com/SSL/openssl-0.9.8r-i386-win32-rev2.zip
  2. Just copy your folder in c drive.
  3. Create openssl.cnf file and download their content from : http://web.mit.edu/crypto/openssl.cnf openssl.cnf can be put any where but path shoud be correct when we give in command prompt.
  4. Open command propmt and set openssl.cnf path C:\set OPENSSL_CONF=d:/openssl.cnf 5.Run this in cmd : C:\openssl-0.9.8r-i386-win32-rev2>openssl.exe
  5. Then Run OpenSSL> genrsa -des3 -out server.enc.key 1024
  6. Then it will ask for pass phrases : enter 4 to 11 character as your password for certificate
  7. Then run this Openssl>req -new -key server.enc.key -out server.csr
  8. Then it will ask for some details like country code state name etc. fill it freely. 10 . Then Run Openssl > rsa -in server.enc.key -out server.key
  9. Run this OpenSSL> x509 -req -days 365 -in server.csr -signkey server.key -out server.crt then use previous code that are on stack overflow Thanks

The above answers are good but with Express and node this will work fine.

Since express create the app for you, I'll skip that here.

var express = require('express')
  , fs = require('fs')
  , routes = require('./routes');

var privateKey = fs.readFileSync('cert/key.pem').toString();
var certificate = fs.readFileSync('cert/certificate.pem').toString();  

// To enable HTTPS
var app = module.exports = express.createServer({key: privateKey, cert: certificate});

Update

Use Let's Encrypt via Greenlock.js

Original Post

I noticed that none of these answers show that adding a Intermediate Root CA to the chain, here are some zero-config examples to play with to see that:

Snippet:

var options = {
  // this is the private key only
  key: fs.readFileSync(path.join('certs', 'my-server.key.pem'))

// this must be the fullchain (cert + intermediates)
, cert: fs.readFileSync(path.join('certs', 'my-server.crt.pem'))

// this stuff is generally only for peer certificates
//, ca: [ fs.readFileSync(path.join('certs', 'my-root-ca.crt.pem'))]
//, requestCert: false
};

var server = https.createServer(options);
var app = require('./my-express-or-connect-app').create(server);
server.on('request', app);
server.listen(443, function () {
  console.log("Listening on " + server.address().address + ":" + server.address().port);
});

var insecureServer = http.createServer();
server.listen(80, function () {
  console.log("Listening on " + server.address().address + ":" + server.address().port);
});

This is one of those things that's often easier if you don't try to do it directly through connect or express, but let the native https module handle it and then use that to serve you connect / express app.

Also, if you use server.on('request', app) instead of passing the app when creating the server, it gives you the opportunity to pass the server instance to some initializer function that creates the connect / express app (if you want to do websockets over ssl on the same server, for example).


You can use also archive this with the Fastify framework:

const { readFileSync } = require('fs')
const Fastify = require('fastify')

const fastify = Fastify({
  https: {
    key: readFileSync('./test/asset/server.key'),
    cert: readFileSync('./test/asset/server.cert')
  },
  logger: { level: 'debug' }
})

fastify.listen(8080)

(and run openssl req -nodes -new -x509 -keyout server.key -out server.cert to create the files if you need to write tests)


The Express API doc spells this out pretty clearly.

Additionally this answer gives the steps to create a self-signed certificate.

I have added some comments and a snippet from the Node.js HTTPS documentation:

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

// This line is from the Node.js HTTPS documentation.
var options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.cert')
};

// Create a service (the app object is just a callback).
var app = express();

// Create an HTTP service.
http.createServer(app).listen(80);
// Create an HTTPS service identical to the HTTP service.
https.createServer(options, app).listen(443);

The minimal setup for an HTTPS server in Node.js would be something like this :

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

var httpsOptions = {
    key: fs.readFileSync('path/to/server-key.pem'),
    cert: fs.readFileSync('path/to/server-crt.pem')
};

var app = function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}

https.createServer(httpsOptions, app).listen(4433);

If you also want to support http requests, you need to make just this small modification :

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

var httpsOptions = {
    key: fs.readFileSync('path/to/server-key.pem'),
    cert: fs.readFileSync('path/to/server-crt.pem')
};

var app = function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}

http.createServer(app).listen(8888);
https.createServer(httpsOptions, app).listen(4433);

If you need it only locally for local development, I've created utility exactly for this task - https://github.com/pie6k/easy-https

import { createHttpsDevServer } from 'easy-https';

async function start() {
  const server = await createHttpsDevServer(
    async (req, res) => {
      res.statusCode = 200;
      res.write('ok');
      res.end();
    },
    {
      domain: 'my-app.dev',
      port: 3000,
      subdomains: ['test'], // will add support for test.my-app.dev
      openBrowser: true,
    },
  );
}

start();

It:

  • Will automatically add proper domain entries to /etc/hosts
  • Will ask you for admin password only if needed on first run / domain change
  • Will prepare https certificates for given domains
  • Will trust those certificates on your local machine
  • Will open the browser on start pointing to your local server https url

Found this question while googling "node https" but the example in the accepted answer is very old - taken from the docs of the current (v0.10) version of node, it should look like this:

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

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

https.createServer(options, function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}).listen(8000);

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to ssl

Requests (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.") Error in PyCharm requesting website A fatal error occurred while creating a TLS client credential. The internal error state is 10013 curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number How to install OpenSSL in windows 10? ssl.SSLError: tlsv1 alert protocol version Invalid self signed SSL cert - "Subject Alternative Name Missing" "SSL certificate verify failed" using pip to install packages ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749) Powershell Invoke-WebRequest Fails with SSL/TLS Secure Channel "ssl module in Python is not available" when installing package with pip3

Examples related to https

What's the net::ERR_HTTP2_PROTOCOL_ERROR about? Requests (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.") Error in PyCharm requesting website Android 8: Cleartext HTTP traffic not permitted ssl.SSLError: tlsv1 alert protocol version Invalid self signed SSL cert - "Subject Alternative Name Missing" How do I make a https post in Node Js without any third party module? Page loaded over HTTPS but requested an insecure XMLHttpRequest endpoint How to force Laravel Project to use HTTPS for all routes? Could not create SSL/TLS secure channel, despite setting ServerCertificateValidationCallback Use .htaccess to redirect HTTP to HTTPs

Examples related to webserver

Nginx upstream prematurely closed connection while reading response header from upstream, for large requests Apache Server (xampp) doesn't run on Windows 10 (Port 80) What is the difference between HTTP 1.1 and HTTP 2.0? Reload nginx configuration The program can't start because MSVCR110.dll is missing from your computer XAMPP Object not found error Amazon AWS Filezilla transfer permission denied how to configuring a xampp web server for different root directory How to open a web server port on EC2 instance Minimal web server using netcat