MetaMask签名授权DAPP登陆
登录流程如何工作
这是如何做到的呢?这部分内容讲说服你,证明这种方式是安全的。所以为什么部分的介绍就比较短了。
如前面所述,我们将忘记区块链。我们有一个传统的Web 2.0客户端 – 服务器RESTful架构。我们将做出一个假设:访问我们的前端网页的所有用户都安装了MetaMask。有了这个假设,我们将展示无密码加密安全登录流程的工作原理。
第1步:修改用户模型(后端)
首先,我们的User
模型需要有两个新的必填字段:publicAddress
和nonce
。此外,publicAddress
需要具有唯一性。你可以保持平常username
,email
和password
字段,特别是如果你想平行实现您MetaMask登录电子邮件/密码登录,但它们是可选的。
如果用户希望使用MetaMask登录,则注册过程也会略有不同,因为注册时publicAddress
将是必填字段。不过请放心,用户永远不需要手动输入publicAddress
钱包地址,因为它可以通过web3.eth.coinbase
变量来提取。
第2步:生成随机数(后端)
对于数据库中的每个用户,在nonce
字段中生成随机字符串。例如,nonce
可以是一个大的随机整数。
第3步:用户获取他们的随机数(前端)
在我们的前端JavaScript代码中,假设存在MetaMask,我们可以访问window.web3
。因此,我们可以通知web3.eth.coinbase
获取当前MetaMask帐户的钱包地址。
当用户单击登录按钮时,我们向后端发出API调用以检索与其钱包地址关联的随机数。像带参数获取例如GET /api/users?publicAddress=${publicAddress}
应该做的事情那样。当然,由于这是一个未经身份验证的API调用,因此后端应配置为仅显示此路由上的公共信息包括nonce
。
如果先前的请求未返回任何结果,则表示当前钱包地址尚未注册。我们需要先通过POST /users
传递publicAddress
请求消息体来创建一个新帐户。另一方面,如果有结果,那么我们存储它的nonce
。
第4步:用户签署Nonce(前端)
一旦前端接收nonce
到先前API调用的响应,它将运行以下代码:
web3.personal.sign(nonce, web3.eth.coinbase, callback);
这将提示MetaMask显示用于签名消息的确认弹出窗口。随机数将显示在此弹出窗口中,以便用户知道她或他有没有签署某些恶意数据。
当她或他接受签名时,将使用带签名的消息(称为signature
)作为参数调用回调函数。然后前端进行另一个API调用POST /api/authentication
,传递一个带有signature
和publicAddress
的消息体。
第5步:签名验证(后端)
当后端收到POST /api/authentication
请求时,它首先根据请求消息体中publicAddress
获取数据库中的对应用户,特别是它相关的随机数nonce
。
具有随机数,钱包地址和签名后,后端可以加密地验证用户已正确签署了随机数。如果确认是这种情况,那么用户已经证明了拥有钱包地址的所有权,我们可以考虑对她或他进行身份验证。然后可以将JWT或会话标识符返回到前端。
第6步:更改Nonce(后端)
为了防止用户使用相同的签名再次登录(如果它被泄露),我们确保下次同一用户想要登录时,她或他需要签署一个新的nonce。这是通过nonce
为该用户生成另一个随机数并将其持久保存到数据库来实现的。
这就是我们管理nonce签名无密码登录流程的方法。
为什么登录流程有效
根据定义,身份验证实际上只是帐户所有权的证明。如果您使用钱包地址唯一地标识您的帐户,那么证明您加密方式拥有该帐户就非常简单。
为了防止黑客获取某个特定邮件及其签名(但不是您的实际私钥),我们会强制需要签名的消息满足以下条件:
-
- 由后端提供
-
- 定期改变
在我们的demo样例中,每次成功登录后我们都改变了它,但也可以设想基于时间戳的机制。
DEMO代码实现
在本节中,我将逐一完成上述六个步骤。我将展示一些代码片段,以便我们如何从头开始构建此登录流,或者将其集成到现有的后端,而不需要太多努力。
为了本文的目的,我创建了一个小型演示应用程序。我正在使用的堆栈如下:
- Node.js,Express和SQLite(通过Sequelize ORM)在后端实现RESTful API。它在成功验证时返回JWT。
- 在前端反应单页面应用程序。
我尝试使用尽可能少的库。我希望代码足够简单,以便您可以轻松地将其移植到其他技术堆栈。
https://cloud.tencent.com/developer/article/1366834