Domc.Dev
Published on

MetaMask Login - React + MongoDB + GraphQL

Authors

If you prefer to watch over read, I recorded this video below walking though this project.

You can also find all the code and a demo of this project in this github repo.

Giving your users the option to login to their accounts using MetaMask is great UX for web3 applications and dapps. Persisting this data in mongo gives you the option to save user details on your own back end and not rely on third party auth providers.

So I set up a MERN stack boilerplate with graphql and apollo client and I’m using this article from Toptal as a reference. The only problem is that the article follows a rest API to communicate with the server and retrieve the information that we need for this login flow. We’re going to be using graphQL with apollo to achieve the same goal, in my experience Graphql is a more popular api for crypto and web3 projects so hopefully some of you will find this helpful. Some of the packages that I’m using are slightly different also and I’ll be using a slightly different approach but the login flow itself is quite simple.

This metamask login method allows you to use a traditional login flow with username and password alongside it. This is great if you need user data that a MetaMask account does not provide such as email and usernames. In my application (Moby) I need to store user emails as my users can opt in for email updates on their portfolios and so this is the perfect method for my use case as I require my users wallet information for this functionality.

I’ll include a link to download this repo on github if you want to use the code as a boilerplate of sorts to set up your application.

So the first thing we need to do is install our dependencies. After you clone this repo just run yarn or npm install to set up both your node server and your react frontend, you will need to create a mongo database for the purposes of this demonstration, you can plug your credentials into the config.js file found in the server project, this is so we have a place to store our user object. I’m using Atlas free tier.

Server

index.js So we have a basic apollo server running here - just remember to import your Mongo credentials from config and pass them into mongoose.

Models/User.js Here is our user model, take note of the nonce field here - it’s required because it’s what’s going to help us prove ownership of our account using metamask to sign a message that includes the initialized number.

TypeDefs.js We need to make sure that we have the field ‘token’ on our User type here so that our server can pass our Javascript web token through to the client and authenticate our user.

Everything else is pretty straight forward - mutations for our login/register functionality are found here also.

Utilis folder We also have some helpers in the util folder that handle validation errors authentication checks.

Client

App.js So on the front end theres a few different web3 packages that we’re using that if you work in web3 development your probably already familiar with. We have web3-react which is a bit of react niceness to wrap our application with their provider that gives us access to our connected wallet information. It also works with a number of different wallets, but we’re going to be focusing on Metamask for this tutorial.

We’re also going to be working with etheres js which is a nice package that allows us to connect to the ethereum blockchain, an alternative that you might be familiar with is web3.js, I’m using etheres here because I find it plays nicer with metamask signatures, I’ll show you why that’s important in a moment.

At the top level of our application we have wrapped our component tree with two providers

AuthProvider and Web3ReactProvider

These are essential to achieve this login flow and they will allow us to access our users wallet information and user data from the server.

In the client you can see here that I have wrapped my component tree with Web3ReactProvider, the web3react provider needs an argument getLibrary and we need to provide this web3 provider from Ethers, you’ll see why in a moment.