How to create an HTTPS server in Node.js?

455,592

Solution 1

For Node 0.3.4 and above all the way up to the current LTS (v16 at the time of this edit), https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener has all the example code you need:

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

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

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

Note that if want to use Let's Encrypt's certificates using the certbot tool, the private key is called privkey.pem and the certificate is called fullchain.pem:

const certDir = `/etc/letsencrypt/live`;
const domain = `YourDomainName`;
const options = {
  key: fs.readFileSync(`${certDir}/${domain}/privkey.pem`),
  cert: fs.readFileSync(`${certDir}/${domain}/fullchain.pem`)
};

Solution 2

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);

Solution 3

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);

Solution 4

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});

Solution 5

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);
Share:
455,592
murvinlai
Author by

murvinlai

Updated on July 08, 2022

Comments

  • murvinlai
    murvinlai almost 2 years

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

  • Larry Battle
    Larry Battle over 11 years
    setSecure is deprecated. Check this out instead stackoverflow.com/questions/5136353/node-js-https-secure-err‌​or
  • clayzermk1
    clayzermk1 over 11 years
    See the official express answer below by @Jacob Marble.
  • clayzermk1
    clayzermk1 over 11 years
    Nice, was just about to post this myself. Thank you. Additionally, I found this article helpful for generating a self-signed certificate.
  • Merlyn Morgan-Graham
    Merlyn Morgan-Graham over 11 years
    This seems to be deprecated since "applications no longer inherit from http.Server"
  • Petr Prazak
    Petr Prazak about 11 years
    This sample doesn't work anymore as the HTTPS implementation was re-done in Node.JS 0.4. See the corresponding docs at nodejs.org. stackoverflow.com/questions/5136353/…
  • wberry
    wberry almost 11 years
    Make sure you put options first in https.createServer, to avoid cryptic errors.
  • Matej
    Matej over 10 years
    Why you setting module.exports? There's no need for that
  • reza
    reza over 10 years
    I am setting up an almost identical https server port 8888 and not sure how to change the routes. when I run curl curl --insecure localhost:8888 curl: (35) Unknown SSL protocol error in connection to localhost:8888 what is the error coming from and how to get around it. When I type localhost:8888 in the browser, it hangs and https:/localhost:8888 gives SSL error
  • Philipp Kyeck
    Philipp Kyeck about 10 years
    posted an up-to-date (v0.10.x) answer below
  • Costa Michailidis
    Costa Michailidis about 10 years
    How do you force http connections through https? Can you do this through DNS, so that no one ever hits your website through plain http?
  • floatdrop
    floatdrop about 10 years
    @Costa you can redirect users from http to https with express-force-ssl or hand written middleware - it pretty straightforward
  • Costa Michailidis
    Costa Michailidis about 10 years
    Thanks, @floatdrop! So, for security reasons I'm wondering if you can eliminate the http server completely. If someone has a cookie from my site, and they hit the http server, which redirects them to the https server, that makes them vulnerable, no?
  • Jay Sheth
    Jay Sheth about 10 years
    This answer is very old and does not work anymore. Please see the answer by pkyeck below, or go to: nodejs.org/api/https.html
  • lewsid
    lewsid over 9 years
    Worked like a charm. This information came in very handy as I run a node.js tool (PDFJS) on top of a PHP app that was recently forced to run over https. The iframe was very unhappy to load my node.js app on an alternate, non-https port.
  • TlonXP
    TlonXP over 9 years
    Also the link is broken
  • Ionică Bizău
    Ionică Bizău about 9 years
    This looks good, but how can I generate the files you are requiring there (*.pem)? I tried following this page, but when opening localhost:8000 in the browser, no data is received (just loading...).
  • Justin
    Justin about 9 years
    @matejkramny, probably because it makes it easy to test.
  • mido
    mido about 9 years
    @IonicăBizău, for generating keys, install openssl, then in cmd prompt, type openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3001
  • user2720864
    user2720864 about 9 years
    cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') should be changed to cert: fs.readFileSync('test/fixtures/keys/agent2-cert.crt')
  • Florian Wendelborn
    Florian Wendelborn over 8 years
    @IonicăBizău you need to directly go to https://localhost:8080. HTTP is NOT HTTPS.
  • Nathan McKaskle
    Nathan McKaskle over 8 years
    Mine says bad password read, what do I do about the key password on the cert?
  • BollMose
    BollMose over 7 years
    I know your answer was right but it does not work on my Mac, until I found this article: engineering.circle.com/… .
  • sakisk
    sakisk over 7 years
    @NathanMcKaskle You can disable the password: Check this guide but if you are using macOS make sure that the generated key length is at least 2048: openssl genrsa -out key.pem 2048
  • Martin Schneider
    Martin Schneider almost 7 years
    this is OT. The OP's question is clear. Certificates are already given.
  • Benjamin
    Benjamin over 6 years
    How about the case of using, var http = require('http').Server(app); rather than createServer. How could I use HTTPS then?
  • ProgramCpp
    ProgramCpp over 6 years
    If I'm not wrong, this creates a server with SSL handshake. Does it also take care of encrypting the responses too? what symmetric encryption is used? Should it be taken care by the server before sending the responses?
  • Chucky
    Chucky over 4 years
    This is a nice explanation but, the provided link in the update section, is broken (gives 500 error)
  • FrenkyB
    FrenkyB over 4 years
    Is it possible to create https-server with folder? So you can put file in it and access that file like localhost:81/main.js
  • Philipp Kyeck
    Philipp Kyeck over 4 years
    @FrenkyB there is github.com/cloudhead/node-static that can help you with that
  • ThN
    ThN almost 3 years
    All these answers are OLD and OUTDATED. I wish StackOverflow would cleanup up questions and answers that are VERY VERY OLD.
  • ThN
    ThN almost 3 years
    All these answers are OLD and OUTDATED. I wish StackOverflow would cleanup up questions and answers that are VERY VERY OLD. createServer DEPRECATED! This function DOESN'T exists anymore.
  • coolaj86
    coolaj86 almost 3 years
    @ThN What isn't working for you? What's a newer, better solution?
  • ThN
    ThN almost 3 years
    @coolaj86 After long time of trial and turbulence (lol), I have figured out my issue. It works now. I had a line var https = require("https").server(app); And when I went to create server with https.createServer(...) I got the error message createServer not found. After changing the line to var https = require("https");, everything fell into place. Thank you...
  • John Slegers
    John Slegers almost 3 years
    What are you talking about? What do you mean createServer doesn't exist anymore? It's still documented in the Node.js v16.5.0 documentation in both nodejs.org/api/http.html & nodejs.org/api/https.html and not flagged as deprecated. Have you actually tried running this code? And, if so, which errors did you get?
  • ThN
    ThN almost 3 years
    actually I figured out my mistake. There was one line that needed changed var https = require('https').Server(app); to var https = require('https'); Now, everything works... Thanks.
  • Boris Ivanov
    Boris Ivanov over 2 years
    thanks a lot buddy for Fastify example
  • Yarik
    Yarik over 2 years
    I had some issues whyle setting up OpenSSL certificate on my Subsystem Linux Windows, for running SSL on localhost for node.js / secure sockets, long story short, I tired out 3-5 "recepies" and the simplest and shortest one was here (10 minutes and it worked out, against 1 day of unlucky tries): flaviocopes.com/express-https-self-signed-certificate (yes it is for Mac but it worked for my Ubuntu 20 )