Goodbye Password, Hello Wallet

We show you how to create user auth with Ethereum wallets

Shain Lafazan
The Notice Board
3 min readSep 21, 2018

--

What if we could identify ourselves online in a hassle-free way? Producing unique signatures and determining the authenticity of a transaction is one of the core components of blockchain technology, so we can harness that behavior to make user authentication a breeze.

Before we get started, here’s a disclaimer: this is an example for demonstration purposes, and does not contain any security constraints. Sending raw signatures and storing them is not secure! Before implementing this in production, precautions such as hashing and salting signatures and removing storage workflows should be considered. Also, never share your private key unless you know what you’re doing!

With that out of the way, let’s continue. Here are the assumptions we make for this auth scheme:

  1. We’re using the Ethereum network.
  2. Ethereum private keys are unique, and (contextually) the personal signatures they produce are unique.
  3. Web3 is available for the client (for example, MetaMask Chrome extension)

To understand how password-less auth will work, let’s go over the basic steps:

Let’s take a look at the Client behavior for registration:

// client.js - Register Workflowfunction authenticateUser(endpoint, key) {
// get wallet from web3 context
const wallet = web3.eth.accounts[0];
// Request the user’s signature
web3.currentProvider.sendAsync({
method: 'personal_sign',
params: [web3.fromUtf8(key), wallet],
from: wallet,
}, (err, response) => {
// TODO: Send result to server
axios.post(endpoint, { wallet, signature: response.result });
});
}
authenticateUser(‘/register, ‘MY_KEY’);

The user must manually “SIGN” to produce a signature.

Congratulations! You’ve just sent unique public and private identifiers for yourself to a remote server. Now, the server can register you and uniquely identify you when you return.

Your registration route might look something like this (especially if you’re using a REST Node + Express backend):

// server.js — Register Workflowapp.post('/register', async (req, res) => {
// create a unique user
const user = await User.create({ wallet: req.body.wallet, signature: req.body.signature });
res.status(200).send({ user });
});

Now, let’s perform a login operation. This should look eerily similar to the register operation:

// client.js — Login Workflow// ...authenticateUser('/login', 'MY_KEY');

This will trigger the same signing workflow, so our server can compare our signature to the signature we sent during the registration workflow:

// server.js — Login Workflow// ...app.post('/login', async (req, res) => {
// find a unique user
const user = await User.findOne({ wallet: req.body.wallet });
// compare signatures to verify user identity
if (req.body.signature !== user.signature) {
return res.status(500).send({ error: '...' });
}
return res.status(200).send({ user });});

Done! With just ~20 lines of code, we have a password-less auth scheme for clients, powered by Ethereum private keys! If you’re reading this, thanks for your unique, identifiable, potentially password-less view.

BitGuild’s mission is to revolutionize the global gaming industry by creating a platform for a brand new class of games that live on the blockchain. Blockchain games completely redefine the relationship between players and developers by facilitating full and true ownership of in-game assets, cheap & safe item trading, cross-game compatibility of items & currency, and more.

Join the community on Twitter, Discord, Telegram, and Facebook.

--

--