How to SSL Secure Your LocalHost

… and connect your dev environment to HTTPS locally.

Recently I had to set up a client’s development environment to be able to communicate with a 3rd party authentication service called Verified.Me.

This service has the user verify their identity by logging in with their banking credentials.

It then retrieves their personal information (name, address, etc), and returns that data to our app in the form of a cookie.

For the user experience, the user would click on a button in the app to create a new account.

This button triggers a redirect, sending the user to the 3rd-party authentication service, and as part of this redirect url we also provide a callback URL and an error URL.

It looks something like this:

https://your-website.com/your/api/route?callbackUrl=https://your-website.com/success/path&errorUrl=https://your-website.com/failure/path

When the user successfully authenticates themselves using their banking credentials, they are returned to the app at the route specified in the callback URL.

Similarly, if the user cancels or fails the authentication, they are returned to our app at the route specified by the error URL.

I encountered 2 problems when attempting to set this service up:

First: none of the URLs provided (base, callback, error) would work with localhost.

This service did not like to see requests come from localhost, nor would it return the user to localhost, and as a result would simply break.

Second: the service required the return URLs to be SSL secured; that is, it required them to be using HTTPS.

The first problem can be solved by creating a localhost alias.

The second problem can be solved by generating keys and certificates for the localhost alias, as well as by signing the certificates ourselves.

Let’s start with the alias.

Creating The Alias

A localhost alias is simply a secondary domain by which we can access localhost.

Said another way, when we boot up an app at say localhost:3000, if we had set up an alias, we can also see localhost running at our-alias-name:3000.

To create an alias, we begin by opening our macbook’s hosts file from our command line:

> sudo nano /etc/hosts

You may need to enter your password. It will be the password you log into your Mac with and the keystrokes will be hidden.

You are now viewing your hosts file from the Nano command line text editor:

Add a new entry at the bottom with the address for home (127.0.0.1) followed by a name for your alias… which can be whatever you want it to be.

Save the change you made to this file and exit the file.

> CONTROL + O
> ENTER
> CONTROL + X

Great! So we have created an alias for our localhost.

Now let’s test it to make sure that we did it correctly and it works.

From the command line root, navigate to your Desktop, create a new React app, and launch the app with yarn.

> cd Desktop
> npx create-react-app my-app
> yarn start

This will start the app on localhost:3000.

Now simply navigate to mywebapp:3000 and you will see the same thing as localhost.

But if we look up at the lock icon beside the URL we can see that the domain is not secured.

Let’s get that handled

Securing The Alias

With the alias in place we have solved our first problem of not being able to use localhost in the redirect urls.

Now all that is left is to secure our localhost alias for use on HTTPS.

To do this we must generate keys and certificates for the alias, as well as make our machine a certificate authority.

In doing so we will effectively authorize our own certificates.

To generate keys and certificates we will be using a handy little command line tool called mkcert.

In your command line, let’s install mkcert.

> brew install mkcert

We are going to follow this command with an optional command that will ensure our certs also work on Firefox.

> brew install nss

Now we can begin using this tool to generate the files we need, as well as make our machine a certificate authority.

In the root of your React app, let’s create a new folder to store our soon-to-be-generated key and cert files.

> mkdir -p .cert

Now, also from our project’s root directory, run the following command to generate a key.pem file and a cert.pem file.

> mkcert -key-file ./.cert/key.pem -cert-file ./.cert/cert.pem "localhost" "mywebapp"

In the above command, we generate the key and cert files in our new .cert folder, and these credentials will apply to every domain that follows in quotes. While we don’t necessarily need to secure localhost, it doesn’t hurt to do it anyways.

Finally, for the browser to see the certs as being secured, they need to be associated with a Certificate Authority.

The easiest way is to simply make ourselves a certificate authority with the following command:

> mkcert -install

Excellent! So we now have everything in place for our app to run on an SSL secured localhost alias. 😁

However, software isn’t inherently intuitive.

Our app still won’t know that we want it to run on HTTPS, nor will it know that we want it to use our new credentials.

So let’s write a script to tell it!

In our project’s package.json file add a new script called start:ssl.

"start-ssl": "HTTPS=true SSL_CRT_FILE=./.cert/cert.pem SSL_KEY_FILE=./.cert/key.pem react-scripts start",

Save the file, shut the app down if it is still running, and restart it with our new script.

> yarn start:ssl

This will open the browser to https://localhost:3000.

If it doesn’t look like it worked, make sure that you are in fact using HTTPS in the browser!

And we can see that localhost:3000 is secure and running on HTTPS.

Now let’s check our alias!

Perfect!

A localhost alias, secured in the browser.

So that’s how you do that. 🚀

We can now securely integrate our app with the aforementioned authentication service, or with any other third-party services we want!

Thanks for reading!

Make sure you bookmark this article for later reference.

Until next time. ✌️

Marshal

Sometimes I write about code. (marshalmurphy.com)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store