Developing HTTPS Services in Node with Self-Signed Certificates


tl;dr use the environment variable NODE_EXTRA_CA_CERTS to trust a self-signed certificate in Node.

If you want to develop HTTPS services in Node, you need a valid certificate issued from a certificate authority that your host trusts. If you’re unfamiliar with those concepts (or how HTTPS works), check this out. If you want to develop a HTTPS service on your local machine in Node using a self-signed certificate, there are a few issues that you need to overcome.

Node and Certificate Authorities

Node has a hardcoded list of Certificate Authorities that it trusts. When you are developing locally with Node, your certificate needs to come from one of those authorities. If you create a self-signed a certificate, chances are that you are not doing so from a Certificate Authority that Node trusts. When you try and use your self-signed certificate in a HTTPS service, you’ll get an error similar to the following:

{ Error: self signed certificate
    at TLSSocket.<anonymous> (_tls_wrap.js:1105:38)
    at emitNone (events.js:106:13)
    at TLSSocket.emit (events.js:208:7)
    at TLSSocket._finishInit (_tls_wrap.js:639:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38) code: 'DEPTH_ZERO_SELF_SIGNED_CERT' }

Node doesn’t trust your certificate, and you won’t be able to use it for any HTTPS Node services. Below are a few ways to address this issue.

Using a self-signed certificate

The first approach you can take is to use the rejectUnauthorized option when making HTTPS requests to your service. If this option is set to false, Node does not attempt to validate the certificate being used against its list of Certificate Authoritites. This will work, but it’s worth noting why this is working: you are telling Node to not validate the authenticity of your HTTPS connection. Doing so opens you up to Man in the Middle attacks, so take care when using this option.

Another approach you can take is setting up a local proxy that terminates SSL/TLS and takes the connection from HTTPS to HTTP. I haven’t actually tried this, but here is what I saw after a quick google .

The third approach, and the one that I find most compelling, is to use the NODE_EXTRA_CA_CERTS environment variable that was added in Node 7.3.0. Using this approach, you give the NODE_EXTRA_CA_CERTS environment variable a file path to a file containing the certificate that you would like to trust. The file that you use can have as many certificates as you like, and it is used in addition to the list of Certificate Authorities that Node already trusts. As an example, if I want to trust a self-signed certificate that I created on my machine, I might execute the following command in my shell – export NODE_EXTRA_CA_CERTS=/c/code/server.crt.

I’m most drawn to the third approach for simplicity. But, YMMV.

Generating certificates for local development

If you want to generate a certificate for local development, something like this will work:

openssl req \
       -newkey rsa:2048 -nodes -keyout domain.key \
       -x509 -days 365 -out domain.crt

Please note that when going through the certificate prompts, you’ll want to set the Common Name to be localhost if you intend to work locally, as opposed to You also need to execute all your local requests to localhost as opposed to More info on that here.

527 Words

2018-05-13 06:05 +0000