You don’t need JWT anymore
By: Miroslaw Shpak
Tags: Authentication, Web3, Blockchain Development, Software Architecture, Ethereum

A simpler way to authenticate users with web3 using signed messages

It’s no secret that the Ethereum login will soon become a user standard and passwords will no longer be needed. Nevertheless, dApp development is still a fairly young direction and many standards for their development are still set.

Now all developers continue to write dApps with old practices, instinctively using the same JWT for authentication. I propose a slightly different approach.

I myself started developing dApps using JWT. From the first project, I felt that authentication always becomes tricky and that there must be something redundant in the process. After a couple of projects, I realized that the JWT itself is redundant. Let me explain why.

This diagram shows how I did authentication on my first few projects. Here the scheme almost wholly repeats the standard procedure with JWT, the only thing is that instead of a login and password, the user sends a signature.

Why do we need to get JWT? After all, even without it, you can reliably identify the user by taking the address from his signature.

Here’s how to simplify it:

Authentication flow with web3-token

The user still generates a signature, but already with an Expire-date inside, so that if an attacker gets the signature, it won’t be useful for long (the same as with the JWT). Further, the signature is placed in the standard Authorization header and processed on the server by taking the user’s address and finding the user in the database. That’s all. And you do not need to constantly update the encryption keys for the JWT on the server, so in general, a lot of responsibility falls off the server.

To simplify this flow even more, I made the web3-token module. To install it, use the command:

$ npm i web3-token

This module can be used both on the server and on the client.

Let’s look at an example, starting with the client-side.

After calling the .sign method, you will see something similar to this (if you are using MetaMask).

MetaMask notification to sign our token

As you can see, the message is completely transparent for the user since they must see what they are signing. So instead of using JSON structure for better readability, I decided to use the same structure as for HTTP headers.

In the body of the message, we see the version of the token and the expire date itself.

Next, here’s what the backend (Node.js) does with this token:

It’s pretty simple, just one line, and the module takes over all cryptography. We magically obtain the user’s address from the signature and find them in the database using this address. Then , for example , you may grant this user an NFT by his address.

The result is a very convenient stateless user authentication method, ideal for hybrid dApps. The only drawback is that it is hard to test in Postman 😀

I would really like something like a standard to come out of this, but until then, I am open to criticism (or possibly questions/suggestions) via telegram @bytesbay or mail miroslaw.shpak@gmail.com. I am also currently preparing a series of articles on real-time blockchain game development with NFT, so stay tuned.

Web3 is just around the corner.