Skip to content

Instantly share code, notes, and snippets.

@jrcharney
Last active March 1, 2023 18:59
Show Gist options
  • Select an option

  • Save jrcharney/e3a0f1804e55991b0932e7e1e65bff80 to your computer and use it in GitHub Desktop.

Select an option

Save jrcharney/e3a0f1804e55991b0932e7e1e65bff80 to your computer and use it in GitHub Desktop.
How to use HTTPS or HTTP/2 in Node.js and why you should use Let's Encrypt.

Using HTTPS or HTTP/2 to create a HTTPS site

HTTP is an unencrypted protocol. It's not secure. A lot of websites offer a way to fix that using Let's Encrypt to set up you HTTPS stuff.

Several webhosting providers have instructions for setting up HTTPS or HTTP/2 on their server.

  • Netlify
  • Dreamhost
  • DigitalOcean
    • via LearnWithJason (Caution: Written in 2016! Instructions and technologies may have changed since then!)
  • Heroku via uplift.ltd
    • Also Heroku via Heroku but with a "Yeah, we're not using this anymore because we suck."

But if you just want to do this on your localhost site, you need to install openssl, which if you have Linux (including WSL for Windows) or UNIX (Mac). Simply requires going to your software manager (APT, Pacman, or Brew) and installing it.

Of course once you have it installed, you can use openssl to create your Key and Certificate files.

openssl genrsa -out localhost.key 2048
openssl req -new -x509 -key localhost.key -out localhost.cert -days 9999 -sub /CN=localhost

The first openssl command will create a localhost.key file. This is the key that will be used by the certificate. The second command uses the key to create localhost.cert which is the certificate file.

Use dotenv

Like anything that needs to be kept secure, you should stick your key and certificate somewhere else. In this case, the .env file.

PORT=8080
SSL_KEY='./localhost.key'
SSL_CERT='./localhost.cert'

Writing an HTTPS site

Node.js has two ways to create an HTTPS site.

  • HTTPS
  • HTTP/2

HTTPS

To add HTTPS, you need to use your key and certificate using the https module.

/**
 * @file index.js
 */
import { createServer } from 'https';
import { readFileSync } from 'fs';
import * as dotenv from 'dotenv';
// more imports...

dotenv.config();
const PORT = process.env.PORT || 8080;

const options = {
    key:  readFileSync(process.env.SSL_KEY),
    cert: readFileSync(process.env.SSL_CERT)
};

createServer(options,(req,res) => {
    // stuff goes here...
}).listen(PORT, () => {
    console.log(`Listening at https://localhost:${PORT}/.`);
});

HTTP/2

HTTP/2 is another way to create HTTPS, but it is supposedly faster than HTTPS.

/**
 * @file index.js
 */
import { createSecureServer } from 'http2';
import { readFileSync } from 'fs';
import * as dotenv from 'dotenv';
// more imports...

dotenv.config();
const PORT = process.env.PORT || 8080;

const options = {
    key:  readFileSync(process.env.SSL_KEY),
    cert: readFileSync(process.env.SSL_CERT)
};

createSecureServer(options,(req,res) => {
    // stuff goes here...
}).listen(PORT, () => {
    console.log(`Listening at https://localhost:${PORT}/.`);
});

Running the site

node index.js

Visit https//localhost:8080/. It should look like your http://localhost:8080/ but now YOUR SITE IS SECURE!

Note: The default port for an HTTPS site is typically port 443. Similarly, the default port for HTTP is port 80. But we've been using port 8080, 5000, 3000, etc. for a while. In a production atmosphere, its probably important to remember that.

There's obviously a few other features that probably should be enabled that Let's Encrypt can do for your online site, but setting up HTTPS locally feels so much more professional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment