Skip to content

An Express HTTPS server with a self-signed certificate

New Course Coming Soon:

Get Really Good at Git

How to create a self-signed HTTPS certificate for Node.js to test apps locally

To be able to serve a site on HTTPS from localhost you need to create a self-signed certificate.

A self-signed certificate is sufficent to establish a secure, HTTPS connection for development purposes. Although browsers will complain that the certificate is self-signed (and as such is not trusted).

To create the certificate you must have OpenSSL installed on your system.

You may have it installed already, just try typing openssl in your terminal.

If not, on a Mac you can install it using brew install openssl (if you use Homebrew). Otherwise, search on Google “how to install openssl on “.

Once OpenSSL is installed, run this command:

openssl req -nodes -new -x509 -keyout server.key -out server.cert

You will be prompted to answer a few questions. The first is the country name:

Generating a 1024 bit RSA private key
...........++++++
.........++++++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:

Then your state or province:

State or Province Name (full name) [Some-State]:

Your city:

Locality Name (eg, city) []:

…and your organization name:

Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:

You can leave all of these empty.

Just remember to set this to localhost:

Common Name (e.g. server FQDN or YOUR name) []: localhost

…and to add your email address:

Email Address []:

That’s it! Now you have 2 files in the folder where you ran the original command:

Both files will be needed to establish the HTTPS connection, and depending on how you are going to setup your server, the process to use them will vary.

Those files need to be put in a place reachable by the application, and then you’ll need to configure the server to use them.

This is an example using the https core module and Express:

const https = require('https')
const app = express()

app.get('/', (req, res) => {
  res.send('Hello HTTPS!')
})

https.createServer({}, app).listen(3000, () => {
  console.log('Listening...')
})

Without adding the certificate, if I connect to https://localhost:3000 this is what the browser will show:

without-cert

With the certificate in place:

const fs = require('fs')

//...

https.createServer({
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.cert')
}, app).listen(3000, () => {
  console.log('Listening...')
})

Chrome will tell us that the certificate is invalid (since it’s self-signed), and will ask us to confirm before continuing (however, the HTTPS connection will still work):

with-cert

Are you intimidated by Git? Can’t figure out merge vs rebase? Are you afraid of screwing up something any time you have to do something in Git? Do you rely on ChatGPT or random people’s answer on StackOverflow to fix your problems? Your coworkers are tired of explaining Git to you all the time? Git is something we all need to use, but few of us really master it. I created this course to improve your Git (and GitHub) knowledge at a radical level. A course that helps you feel less frustrated with Git. Launching Summer 2024. Join the waiting list!
→ Get my Express.js Handbook
→ Read my Express.js Tutorial on The Valley of Code

Here is how can I help you: