Posted on Leave a comment

Create SSL Site At Your Localhost With MAMP/NodeJS In 5 Minutes

ssl on localhost

As a software developer, I usually found myself frustrated looking at the browser with the following notice when loading my local site:

Create SSL Site At Your Localhost With MAMP/NodeJS In 5 Minutes 1

Yes, the infamous “Your connection is not private notice”. You can bypass that by typing “THISISUNSAFE” in Chrome/Edge. However, a hack is still a hack. You deserve a good solution.

Today, I’m the solution provider. Let’s walk with me to make https://abc.local load with SSL like a normal secure site.

Here is the environment:

  • OS: MacOS 10.15.3
  • MAMP running Apache 2.4

Your environment may be different, however, the method is applicable to other environments running Apache.

Let’s get started.

How to configure Apache 2.4 on MAMP to enable local secure site

Step 1: Add your site to /etc/hosts

This is the easiest one. To host a site on your localhost, you need to add a record of that site to /etc/hosts file so when you type that site into your browser address bar, the browser know to look for it at your localhost.

In our case, we need to add abc.local to /etc/hosts.

Let’s open /etc/hosts by typing:

sudo vim /etc/hosts

I’m using vim as the text editor, however, you can use any other program you like. The important thing to note is opening it with sudo or you cannot save your changes.

On Windows, the equivalent of /etc/hosts is C:\Windows\System32\drivers\etc\hosts. Just open your notepad with Administrator right and then open the hosts file and you’ll be fine.

Let’s insert:

127.0.0.1 abc.local

at the end of the hosts file and save then close it. Like this:

Create SSL Site At Your Localhost With MAMP/NodeJS In 5 Minutes 2

And you are done with step one!

Step 2: Enable NameVirtualHost, SSL, Vhosts In Apache

In this step, we are going to modify some of Apache’s configurations so it’ll accept SSL, VirtualHost records and Named virtual host. If you have been using MAMP (or XAMPP) for a while, you know how to access the server via http://localhost… However, to access localhost with custom domain name like abc.local, you need to do the following:

First, open the file at /Applications/MAMP/conf/apache/httpd.conf with your favorite text editor. I’ll use Vim as usual.

Now, look for the following lines:

Include /Applications/MAMP/conf/apache/extra/httpd-ssl.conf
 Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf

And remove the # character at the beginning of those lines.

Save the file and quit.

Next, let’s open /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf to enable name based virtual hosting.

Let’s add the following lines if they are not available or commented:

NameVirtualHost *:80
NameVirtualHost *:443

Then save the file and quit.

You are ready for step 3!

Step 3: Generate your self signed SSL certificates

To generate a certificate for your site, open terminal and run the following command:

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout abc.local.key -out abc.local.crt -extensions san -config \
  <(echo "[req]"; 
    echo distinguished_name=req; 
    echo "[san]"; 
    echo subjectAltName=DNS:abc.local,DNS:developer.abc.local,DNS:www.abc.local,DNS:api.abc.local,IP:10.0.0.1,IP:127.0.0.1
    ) \
  -subj "/CN=abc.local"

As you can see, in the script, I didn’t just generate certificate for abc.local. I also generate certificate for a bunch of subdomains like www, developer… If you need SSL for subdomain, you can add more DNS record. One caveat though, you cannot add subdomain of subdomain. For example, info.developer.abc.local would not work.

You can also notice that the params -day 3650. That means the certificate is valid for 10 years! How about 100 years? Just replace 3650 with 36500.

generating ssl certificate for the local site

As you can see, I’ve successfully generate the certificate files with the command. You’ll get two files: abc.local.key and abc.local.crt. Let’s put these two files in /Applications/MAMP/conf/apache/ssl. If this folder is not available, you need to create it.

Phew! You’ve done a lot. There is two more steps before you can load your site over SSL. Let’s get to step 4!

Step 4: Create your virtual host record in httpd-ssl.conf

Remember httpd-ssl.conf? You’ve seen this file earlier in the post. Let’s open it and add the following record at the end of the file:

<VirtualHost _default_:443>
	ServerName abc.local
	ServerAlias abc.local
	DocumentRoot "/Applications/MAMP/htdocs/abc/"
	ErrorLog "logs/abc.local-error_log"
	CustomLog "logs/abc.local-access_log" common

	SSLEngine on
	SSLCertificateFile  "/Applications/MAMP/conf/apache/ssl/abc.local.crt"
	SSLCertificateKeyFile  "/Applications/MAMP/conf/apache/ssl/abc.local.key"
</VirtualHost>

Let’s safe the file and quit. Now, it’s time to work on the certificate.

Step 5: Trust your certificate

Since your certificate is self-signed, you need to manually trust it. Let’s open the abc.local.crt file by double clicking on it:

Install the certificate

Now, select System as Keychain and click on Add. The system will ask you to enter password. Do as asked to complete this step.

Now, look for abc.local in the list of certificates and double click on that.

Trust the self-signed certificate

Select Always trust and close the window. You may be asked to enter your password again. Do so as this is the last step you need to work with the certificate!

Final step: Restart MAMP and view your site

Now, go to your browser and type https://abc.local, you should see the site is successfully loaded without any security warning. Clicking on the lock icon, you’ll see the site is trusted:

SSL certificate is working on localhost mac MAMP

You may see a 404 page. That’s expected since our path to the site is not available yet (htdocs/abc). Let me create a very quick index.html in htdocs/abc so you’ll see the content.

Hello from http on localhost MAMP

That’s it! now you have the SSL certificate valid for 10 years!

Bonus tips: How to make SSL works on webpack-dev-server

Now you know how to create secure site on localhost with MAMP. Using the same certificate files, you can make any sites with webpack dev server or other nodejs based app secure on localhost too.

In this example, I’m going to create a new Vue cli project and also create a vue.config.js file at the project root. The content of the file is simple as follow:

var fs = require('fs')
module.exports = {
    devServer: {
        host: 'abc.local',
        port: 8081,
        https: true,
        key: fs.readFileSync("/Applications/MAMP/conf/apache/ssl/abc.local.key"),
        cert: fs.readFileSync("/Applications/MAMP/conf/apache/ssl/abc.local.crt"),
    }

}

As you can see, the key is to set https to true and point key and cert options to the files we have created previously.

When I run the app with npm run serve, you can see that the app is served over https and there is no certificate problem:

Create SSL Site At Your Localhost With MAMP/NodeJS In 5 Minutes 3

Conclusion

I don’t know about you but the day I discovered installing SSL for my local site this easy, my life changed. I no longer have to rely on options like Flywheel’s local just to get the https to work. Hopefully, this tutorial helps you has much it helped me. If you have any suggestions, please let me know in the comment below.

Posted on Leave a comment

Passing Data Back And Forth Between Child and Parent in Vue

If you are developing in Vue long enough, you will meet a scenario when you need to pass data from child to parent or parent to child. That’s what I’m going to show you in this post. I’ll make it short and to the point so you can continue working on your great project fast.

Passing data from parent to child in Vue

Passing literal value

To pass data from parent to child, you need to use props. Let’s take the following example:

I have a child component called Cow like this:

<template>
    <div >
        <h3>{{ parentMessage }}</h3>
    </div>
</template>


<script>
export default {
    name: 'Cow',
    props: {
        parentMessage: String
    }
}
</script>

As you can see, the Cow component has a prop called parentMessage. In the parent component, we can pass data to Cow using this prop.

<template>
  <div id="app">
    <Cow parentMessage="I am a cow" />
  </div>
</template>

Then, you see the message appears as expected:

Vue passing literal props

It’s easy, isn’t it?

Updating props

What if you want to change the prop to something else? It’s quite simple, fortunately.

First, let’s create a data property in the parent component called newParentMessage. We are going to bind this property to the Cow’s prop.

In the parent component, it looks like this:

<Cow :parentMessage="newParentMessage" />

You can see that we put the colon at the beginning of the prop. This signifies we are binding the prop to a variable, not literal value as before.

Let’s create a new button in the parent component so when we click on that, the message to Cow component changes.

<button>Change parent message</button>

We need to create a click handler for this button in the parent component. Let’s call it changeParentMethod. Let’s change the message to “I’m just a poor cow”:

changeParentMessage() {
      this.newParentMessage = "I'm just a poor cow"
    }

We also need to bind the click handler to the button. So, this is the final code of the button:

<button @click="changeParentMessage">Change parent message</button>

Here is what the page look like:

Passing Data Back And Forth Between Child and Parent in Vue 4

If I click the button now, you’ll see that the message is changed.

Vue send data from parent to child

We have successfully pass data from parent to child. Let’s tackle the next challenge: passing data from child component to parent.

When you need to pass data from child to parent in Vue, use $emit. What $emit does it to send a event and in the parent component, you need to have a event handler to catch that event.

Sounds confusing? Let’s see a graph:

Sending data from child to parent component with event

Still confusing? Let’s code!

So currently, the cow message is “I’m just a poor cow”. What if since the start of this post, the cow has been working insanely and got rich? It feels the need to update the status to parent saying: “I’m not poor anymore”.

Let’s help the cow do that. He’s a cool cow.

In the Cow component, let’s create a button so we can send the update. On this button click we will emit an event called update_cow_status along with the data it wants to send.

<button @click="updateFinancialStatus">Update cow status</button>

Next, we need to create the function updateFinancialStatus in Cow component to actually emit the event update_cow_status.

updateFinancialStatus() {
            this.$emit('update_cow_status', {
                message: "I'm not poor anymore",
                netWorth: "$400Bn, with a B!!!"
            })
        }

As you can see, we emit the event along with a data object. The next task is to get the data in parent.

In the parent component, let’s register a handler for update_cow_status event. This is how you do it:

<Cow @update_cow_status="getCowMessage" :parentMessage="newParentMessage" />

As you can see, you need to put the event name in the Cow component. Let’s create the getCowMessage in parent’s methods. I’ll keep it simple to just log the message from Cow.

getCowMessage(message) {
        console.log(message)
    }

Now, let’s see our page:

Passing Data Back And Forth Between Child and Parent in Vue 5

When I click on Update cow status button, I’ll get the following data in the console:

Passing data from child component to parent in Vue

As you can see, we have successfully passed the data from child component to parent with $emit.

Source code

If you need the full source code, you can download it here:

Conclusion

Passing data from child to parent and parent to child is very useful when working on small projects. In larger projects, you might want to use Vuex to store and update data and share such data between components.