DEV Community

AnggaPurz
AnggaPurz

Posted on • Updated on

User Authentication with Web3

Hi, I'm assume you're familiar with Web3, and have understanding about cryptography, DeFi or Web3 Project.

I will introduce you to a new way of User Authentication using Web3 technology (Actually using power of Cryptography).

If you ever land yourself to DeFi or Web3 Project, you must be aware that the platform never force you to Login into platform. It's simply because in Web3, we don't store your personal information. We recognize you by your signature (We're not talking about your handwrite signature, it's about Digital Signature).

You also must be aware that you will require to install a Wallet to join into Web3/Blockchain World. This wallet will be used to manage your private key, and used to sign your transaction that will be send to blockchain. (By any chance, NEVER SHARED YOUR PRIVATE KEY)

Currently, I have a "hybrid" project. I called this project "hybrid" because it utilize power of web3 but most the feature are web2.



What are you talking?!

It must be a bit confusing, I will give you a litte context. So, the Play to Earn games is getting hype in Web3 World. There is a lot of games like Axie Infinite, Splinterlands, Sandbox and many more. And my current project is a Play to Earn games, users will need to buy a NFT, and then used their NFT to play and gained reward.

After a research that have been done by UX team, they found that most of crypto games are a bit annoying to players because it need to do a lot of signing using Wallet, and this submitting process to blockchain is not cheap (At that time, Gas Price on Ethereum was Crazy).

Engineer team also consider that most of game data (data that generated when player play the games) is not necessary to be written on blockchain. So we decided to using NoSQL Database to store game data. And then UX team asking about how the user onboard to the games? Do they need to login using Email/Username & Password?. Well, login using email and password just not really "Web3 things".

We want to identified the player without taking their personal information. So we decide to utilize the essential power of Blockchain. The Cryptography Signing.



Yohohohoo

So, I will show you how to make user authentication on EVM Blockchain Based, using Ethers.js & Metamask. You can pick any framework for your Backend.

Web3 Login Mechanism

User request Nonce to Backend

User will send request to Backend to retrieve information about User's Nonce.

Backend send Nonce to User.

User will retrieve the Nonce. User will construct a message that contain information about the Nonce. Let say the nonce is 100, the message will be is Hi I wanna play the Games | 100

User Sign Message & Wallet Generate Signature

User need to sign a message, we will utilize ethers.js library.

// This nonce come from Backend
const nonce = 100;

// Get User's Public Key
const [account]: string[] = await window.ethereum.request({
    method: 'eth_requestAccounts',
});
const publicKey = await ethers.utils.getAddress(account);

// Sign Message
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const message = `Hi I wanna play the Games | ${nonce}`;
const messageUtf8Bytes = ethers.utils.toUtf8Bytes(message);
const testBytes = ethers.utils.arrayify(messageUtf8Bytes);
const signature = await signer.signMessage(testBytes);
const accountSignature = {
    publicKey: publicKey,
    message: message,
    signature: signature,
};
Enter fullscreen mode Exit fullscreen mode

User submit Signature, Message & Public Key

After sign the message, user will get the signature. User need to submit Signature, Message & Public Key to Backend.

Verify & Validate Signature

User received Signature, Message & Public Key. Backend will check the Nonce on the message, this Nonce must be correct with the Nonce that written on Backend Database. To Validate the Signature, Backend will need to utilize ethers.js library.

const checkValidSignature = (message, signature, pubKey) => {
  const messageUtf8Bytes = ethers.utils.toUtf8Bytes(message);
  const arrayifyMessage = ethers.utils.arrayify(messageUtf8Bytes);
  const recoveredAddress = ethers.utils.verifyMessage(
    arrayifyMessage,
    signature
  );
  const publicKeyLowerCase = pubKey.toLowerCase();
  const recoveredAddressLowerCase = recoveredAddress.toLowerCase();
  if (publicKeyLowerCase === recoveredAddressLowerCase) {
    return true;
  }
  return false;
};
Enter fullscreen mode Exit fullscreen mode

Send Auth Token

If the signature is valid and user send correct nonce, Backend will give Authentication Token to User. This token will be used by user to authenticate themself when play the game.



So, we are not store any Personal Information about users. We don't have a Users table on Backend to store user's username & password.



This is an adequate method that you can apply when build Hybrid apps. You still able to identified your users without collecting their personal information.



Notes
In step above, we signing message using standard EIP-191. If you consider about to have more complex message to sign, you can use EIP-712

Top comments (0)