流程
- 前端调用随机数接口nonce,传入一个用户钱包地址。
- 比如说用户安装了MateMask浏览器插件,通过MetaMask API可以获取用户钱包地址address。
- 随机生成一个随机数,通过SIWEMessage(Signed-In with Ethereum)封装,传入address等信息,将SIWEMessage保存到Redis中【钱包address作为key,siwe.toMessage()作为value】。返回前端SIWEMessage,这个message就是前端要签名的文本。
- 前端通过ethers.js【专门和以太坊区块链交互】 API 验证message,通过MetaMask中获取的用户私钥,会生成签名signature。
- 前端调用login接口,传入我们的address和signature。
- 根据address从Redis中拿出SIWEMessage,利用签名和SIWEMessage得到公钥,使用公钥获得address,如果address和我们传入的钱包地址一致,说明登录成功。
PS:MetaMask是做什么的?
Web3钱包,钱包中保存了自己的公钥和私钥信息,私钥用于签名,证明是你在进行当前行为,公钥用于验证,验证是本人的操作。
解释
如果之前没有接触过这方面的东西,这样只看流程肯定是很困难的,这里我想到了一个很好的例子可以解释:
比如我们的网站就是一个私人俱乐部,那么门口有一个保安需要验证我们(前端、用户)的身份,保安就是我们的后端服务。
我们手里有一个会员卡(MetaMask 钱包 / 其他ETH钱包),保存了自己的公钥和私钥,当然还有钱包地址。
这时我们想要进入俱乐部,我们给保安展示了钱包地址,保安(后端)使用钱包地址给我们生成了一个带有随机编号【这个随机编号是为了防止别人模仿】的纸条(纸条就是我们的SIWE消息,封装了nonce、address、chainId等信息),并且会把纸条内容放到Redis。
我们拿到这个纸条,如果你确实想要进入,需要你使用私钥确认(实际是调用ethers.js操作),确认后我们会得到一个签名signature。
保安拿到你的签名和钱包地址,通过钱包地址从Redis中拿出纸条,利用拿出来的纸条和签名,通过椭圆曲线数字签名算法(ECDSA) 可以恢复公钥,通过公钥可以获得公钥的address。最后将通过公钥获得的address和你的钱包地址进行对比,如果相同,我们就可以执行后续的登录逻辑了。
图示
最后·,自己画了一个图,大家可以看一看: