Metamask Wallet

MetaMask is a bridge that allows you to visit the distributed web of tomorrow in your browser today. It allows you to run Ethereum dApps ...

Authenticating users to your web app using metamask and nodejs

A step-by-step guide with code snippets for implementing a web3 login flow.

So you are building a web3 web app and now comes the scary part where you need to authenticate users and make sure that some of your service’s routes are only accessible upon proper authentication. Do not worry, you stumbled into the correct article.

In this article we’ll be generating and using jwt (json web tokens) to allow users to access protected routes in nodejs which require the user to be authenticated (such as updating their own profile details). The difference is that, instead of the user providing a username and password, they will only be using their metamask wallet for authentication. Here are the technologies we’ll be using:

  • Nodejs for our backend/api.

  • Passportjs for generating jwt tokens.

  • Metamask for the front-end login.

  • Vuejs and Nuxtjs for our frontend (you should also be able to convert this code into other frameworks such as React).

For the purpose of keeping this article short I will not be diving deep into some of the topics mentioned bellow (such as criptography, client state management, performing http requests, connecting nodejs to a database, …), this article should serve as a quick step-by-step guide for any developer to quickly implement this web3 jwt authentication flow in their app.

Authentication flow

The authentication flow works as following:

A nonce is, as per its definition, an arbitrary number that can be used just once in a cryptographic communication. In this article we’ll be using the following code for generating random nonce in javascript:

nonce = Math.floor(Math.random() * 1000000);

Additionally, if it is the first time the user is logging into the platform we will automatically register him by adding him to our users database and automatically assigning him a nonce.

Front-end setup

In my case, I created the following vue component which will have all of the required logic mentioned above:

In case the user does not have metamask installed it will ask the user to install it first:

The template html code (using Vuejs and Nuxtjs) is as following:

And the core associated javascript code is as following. Note that, in this code, we are using axios for performing the http requests and vuex for managing state locally in our web app.

In our local app vuex state we are doing the following when calling the metamask/ethereum getter:

ethereum: state => { if(process.client) { return window.ethereum } }

The full script code including other mentioned methods for this Vue component can be found here.

Back-end setup

On the backend side, we implement the following routes in Nodejs:

The complete code and other routes for the above file can be found here.

You’ll also need to create a setup for passportjs similar to the following:

The JWT_SECRET is a string which will be used to decrypt the jwt tokens. It can be anything you want.

User experience

Assuming that you correctly implemented the above mentioned setup you should now have a user login flow similar to the following:

You can customize the message shown in metamask to be anythnig you want. Just make sure that the complete string (message + nonce) is the same in both the front-end and the back-end.

The front-end application will now have a jwt token which it can now append to any http requests it makes to access protected api routes.

Creating protected routes in nodejs

You can easily create a protected route like this:

In this example the route will use the passportjs middleware to verify that the provided jwt token is valid before running any of the route’s code. Otherwise, it will return an unauthorized message to the user.

Conclusion

This article was a short and practical guide into quickly implementing a web3 jwt authentication flow in your application. In case you get stuck or want to further understand some of the topics covered above I would recommend checking out these resources:

Happy coding!

Last updated