 I build a lot of proofs of concept at [ConsenSys](https://consensys.net/enterprise/) for various clients and usually they want something that leverages the [Ethereum](https://medium.com/@asmiller1989/what-is-ethereum-c82a4b558553) blockchain to solve some business use case. Strangely, these systems often get designed with standard web logins (i.e. with a username and [password](https://hackernoon.com/tagged/password)). I always ask myself why I’m designing things this way since, after all, this is an annoying aspect of every web application that Ethereum can solve **today**. So I’m finally putting my foot down and designing that solution. ### JSON Web Tokens One very popular way to log into a standard web system (and/or use its API) is to submit a password (which is hashed client side) to an authentication endpoint and receive a token in return. This is (usually) called a JSON Web Token and is typically valid for some finite period of time (minutes to days). [Here](https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens) is a nice tutorial on a standard implementation. JSON Web Tokens are nice and dandy, but I got to thinking that it’s very easy to authenticate yourself on the blockchain. In fact, when you use Ethereum, you are constantly doing it. If you think of an Ethereum address (which is just a sha3 hash of your public key) as an account on a website, it is very easy to prove you own that account by signing a piece of data with your private key. This data is arbitrary and can be any random string that the website’s API serves up. Thus, we can use an address as a username and bypass the need for a password. In fact, we don’t even need to use the blockchain to do this. Here’s what it looks like using Express: First we need to do an elliptic curve signature with a private key: var ethUtil = require(‘ethereumjs-util’); // >=5.1.1 var data = ‘i am a string’; // Elliptic curve signature must be done on the Keccak256 Sha3 hash of a piece of data. var message = ethUtil.toBuffer(data); var msgHash = ethUtil.hashPersonalMessage(message); var sig = ethUtil.ecsign(msgHash, privateKey); var serialized = ethUtil.bufferToHex(this.concatSig(sig.v, sig.r, sig.s)) return serialized Don’t worry too much about what these parameters are yet. There is some cryptography going on here and I encourage you to read up on elliptic curve signatures. The [Bitcoin wiki](https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm) is a decent place to start. Anyway, once we have our signature components, we can package them along with the user’s address and send it all to an authentication endpoint. **POST /Authenticate** var jwt = require(‘jsonwebtoken’); var ethUtil = require('ethereumjs-util'); function checkSig(req, res) { var sig = req.sig; var owner = req.owner; // Same data as before var data = ‘i am a string’; var message = ethUtil.toBuffer(data) var msgHash = ethUtil.hashPersonalMessage(message) // Get the address of whoever signed this message var signature = ethUtil.toBuffer(sig) var sigParams = ethUtil.fromRpcSig(signature) var publicKey = ethUtil.ecrecover(msgHash, sigParams.v, sigParams.r, sigParams.s) var sender = ethUtil.publicToAddress(publicKey) var addr = ethUtil.bufferToHex(sender) // Determine if it is the same address as 'owner' var match = false; if (addr == owner) { match = true; } if (match) { // If the signature matches the owner supplied, create a // JSON web token for the owner that expires in 24 hours. var token = jwt.sign({user: req.body.addr}, ‘i am another string’, { expiresIn: “1d” }); res.send(200, { success: 1, token: token }) } else { // If the signature doesn’t match, error out res.send(500, { err: ‘Signature did not match.’}); } } So basically, given some piece of data, an address, and the components of an EC signature, we can cryptographically prove that the address belongs to the person who signed the data. Pretty cool, huh? Once we are satisfied the signature and address match, we can sign a JSON Web Token for that address server side. In this case, the token is valid for 1 day. Now we just need to put in some middleware to guard any routes that would be serving or modifying protected information. **middleware/auth.js** function auth(req, res, next) { jwt.verify(req.body.token, ‘i am another string’, function(err, decoded) { if (err) { res.send(500, { error: ‘Failed to authenticate token.’}); } else { req.user = decoded.user; next(); }; }); } **app.js** // Routes app.post(‘/UpdateData’, auth, Routes.UpdateData); … If the provided token corresponds to the user who sent the request, we continue to requested route. Note that the middleware **modifies the request**. It is this new \`user\` parameter that we need to reference because we know it got set in our middleware. **POST /UpdateData** function UpdateData(req, res) { // Only use the user that was set in req by auth middleware! var user = req.user; updateYourData(user, req.body.data); ... } And there we have it! Your user has literally _signed_ in, but didn’t need a password. ### UI stuff But how does a user actually sign this data in the browser? [Metamask](https://metamask.io/) to the rescue! [Metamask](https://hackernoon.com/tagged/metamask) is a neat chrome extension that [injects web3](https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md) into your browser window. **mycomponent.jsx** makeSig(dispatch) { function toHex(s) { var hex = ‘’; for(var i=0;i<s.length;i++) { hex += ‘’+s.charCodeAt(i).toString(16); } return \`0x${hex}\`; } var data = toHex(‘i am a string’); web3.currentProvider.sendAsync({ id: 1, method: 'personal\_sign', params: \[web3.eth.accounts\[0\], data\] }, function(err, result) { let sig = result.result; dispatch(exchange.authenticate(sig, user)) }) } } render(){ let { dispatch, \_main: { sig } } = this.props; if (Object.keys(sig).length == 0) { this.makeSig(dispatch); } return ( <p>I am a webpage</p> ); } This will trigger Metamask to pop up a window asking the user to sign the message:  Once the callback is invoked, it will call the following action: authenticate(sig, user) { return (dispatch) => { fetch(\`${this.api}/Authenticate\`, { method: 'POST', body: JSON.stringify({ owner: user, sig: sig}), headers: { "Content-Type": "application/json" } }) .then((res) => { return res.text(); }) .then((body) => { var token = JSON.parse(body).token; dispatch({ type: 'SET\_AUTH\_TOKEN', result: token}) }) } } And once you have the auth token saved in your reducer, you can call your authenticated endpoints. And there we have it! Note that `v`, `r`, and `s` values must be recovered from the signature. Metamask has a [signature util module](https://github.com/MetaMask/eth-sig-util) that shows how the signature is constructed. It can be deconstructed like this: var solidity\_sha3 = require('solidity-sha3').default; let hash = solidity\_sha3(data); let sig = result.result.substr(2, result.result.length); let r = sig.substr(0, 64); let s = sig.substr(64, 64); let v = parseInt(sig.substr(128, 2)); where `r` will be parsed as either `0` or `1`. Note also that this uses the [solidity-sha3 module](https://github.com/raineorshine/solidity-sha3) to make sure this hashing algorithm is the same one being used as solidity’s native hashing method (we are hashing the hex-string that was signed earlier). ### Production ready I can’t emphasize enough that _every_ web application using JSON web tokens could easily take advantage of this **today**. Any user with a Metamask extension could simply bypass the login screen with arguably better security than whatever you’re currently using to manage logins. This means fewer forgotten passwords, less wasted time, and a happier user base. And, you know, if you want your users to pay each other (or you, or users on on any other system that uses this) without an intermediary or if you want to take advantage of Ethereum’s million other [features](https://github.com/ethereum/wiki/wiki), this sets you up to do that too. Make the switch today. [Join](https://www.reddit.com/r/ethereum/) us Ethereum folk and conquer the world. — — — — _The views expressed by the author above do not necessarily represent the views of Consensus Systems LLC DBA Consensys. ConsenSys is a decentralized community with ConsenSys Media being a platform for members to freely express their diverse ideas and perspectives. To learn more about ConsenSys and Ethereum, please visit our website. And if you liked this piece, sign up_ [_here_](http://consensys.us11.list-manage.com/subscribe?u=947c9b18fc27e0b00fc2ad055&id=257df01285) _for our weekly newsletter._