There are a number of reasons you may wish to use HTTPS as part of your web application development workflow:
- Your app will likely be deployed to users via HTTPS; the closer your development environment is to production, the less likely you are to run into bugs.
- Browsers behave differently in secure contexts, and you want to avoid production-only surprises.
- You might be integrating with third-party services or APIs that require the use of HTTPS.
Keep reading to find out how to set up SSL for local development.
Unless you are developing on a remote development environment with a static IP address, you won’t have a unique domain name that points to your development environment (and even if you are, you may not want or need one). Without a unique domain name, our only option for and SSL certificate is a self-signed one for local use only. Use this command to generate one:
tl;dr: Use the command below to generate your self-signed certificate and private key.
openssl req -x509 -out localhost.crt -keyout localhost.key -newkey rsa:2048 -nodes -subj '/CN=localhost' -extensions EXT -config <(printf "[req]\ndistinguished_name = dn\n[dn]\nCN=localhost\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
Let’s pick that command apart. Feel free to skip to step 2 if you don’t care about the details.
openssl req- We’re using the
opensslprogram to generate our certificate.
opensslhas many sub-commands; the one we are using is
req, which is for generating certificates and certificate requests.
-x509- Output a self-signed certificate (rather than a certificate signing request that you might send off to a certificate authority—often called a “CA” for short—to be verified and signed for production use).
-out localhost.crt- Write the certificate to a file called
-keyout localhost.key- Write the private key to a file called
-newkey rsa:2048- Generate and use a new private key (as opposed to an existing key, which you’d specify with the
-keyoption) of 2048 bits using the RSA algorithm.
-nodes- Do not encrypt the private key.
-subj '/CN=localhost'- Sets the subject of the certificate request. For production certs, this would include information about the company or business seeking the certificate (such as location, department, email address, etc.), but since this is a development-only certificate, the only necessary information is the “common name” (“CN” for short),
-extensions EXT- Specifies that the extensions section of our config is delineated with a header titled
EXT. That config is defined in the next part of the command.
-config <(printf "...")- The
-configoption takes a file name containing configuration options, but rather than use a separate file we use input redirection (the
<character) and a subshell (the command embedded between parentheses, which returns the string config) to pass the config contents directly, for convenience.
The contents of the configuration are shown more readably below:
[req] distinguished_name = dn [dn] CN=localhost [EXT] subjectAltName=DNS:localhost keyUsage=digitalSignature extendedKeyUsage=serverAuth
[req]- Options for the
reqsubcommand are below this heading.
distinguished_name = dn- Indicates that the distinguished name fields will be found in a section of the config titled
[dn]- The heading for the fields as indicated above.
CN=localhost- The common name (“CN”) for the certificate; in this case:
[EXT]- The heading for the extensions, as indicated by the
subjectAltName=DNS:localhost- Indicates that the certificate should match the
keyUsage=digitalSignature- Indicates that the key may be used for signing the certificate.
extendedKeyUsage=serverAuth- Indicate that in addition to signing the certificate, the private key will also be used to identify the server for SSL/TLS.
Now your local operating system needs to know that the certificate is trustworthy. (Otherwise you’ll see a warning when you access
https://localhost that the certificate is not trusted. This warning can be bypassed but trusting the certificate at the OS level gives a smoother development experience.)
For macOS, this can be achieved by following these steps:
- Open the Keychain Access app.
- Drag and drop your
localhost.crtfile onto the app.
- Right click on the new certificate entry and choose “Get Info”.
- Expand the “Trust” section of the Get Info dialog.
- For “Secure Sockets Layer (SSL)”, choose “Always Trust”.
- Close the dialog and input your password (or TouchID) to save the changes.
There should be a similar process for trusting the certificate in Windows and Linux.
If you’re working on a team, write some documentation for your teammates on how to do this (or point them to this article) so that new engineers can get up and running quickly.
Lastly, your development server applications need to be updated to use the certificate and private key. This will be different for each language and framework. Here are some examples:
For Netlify, the
netlify dev server can be configured to use your SSL certificate in development by adding the following to your
[dev.https] certFile = "localhost.crt" keyFile = "localhost.key"
For Node.js servers, pass the
cert options to
Once configured, you should be able to access your development server via HTTPS on