如何使用Web3.js实现SIWE(以太坊登录)客户端功能?
用Web3.js实现SIWE客户端签名功能
完全可以用Web3.js替代ethers.js实现SIWE(Sign In With Ethereum)的客户端签名部分,核心是利用Web3.js的personal.sign方法完成符合EIP-191规范的签名,和ethers.js的signMessage行为一致。以下是完整实现步骤和代码:
实现步骤
- 初始化Web3实例并连接钱包
- 请求用户授权账户
- 构造符合SIWE规范的消息
- 调用Web3.js的签名方法完成签名
代码示例
1. 初始化Web3并连接钱包
// 初始化Web3实例,基于MetaMask注入的window.ethereum const web3 = new Web3(window.ethereum);
2. 获取授权账户
// 请求用户授权并获取当前账户 const accounts = await web3.eth.requestAccounts(); const userAccount = accounts[0];
3. 构造SIWE消息
首先需要安装siwe库来生成符合规范的消息:
npm install siwe
然后生成消息:
import { SiweMessage } from 'siwe'; // 生成随机nonce(需存储用于后续后端验证) const generateNonce = () => Math.random().toString(36).substring(2, 15); const siweMsg = new SiweMessage({ domain: window.location.host, // 当前域名 address: userAccount, statement: 'Sign in with Ethereum to our DApp', // 自定义签名声明 uri: window.location.origin, // 当前站点URI version: '1', chainId: 1, // 链ID,主网为1,测试网如Goerli为5 nonce: generateNonce(), // 可选:expirationTime: '2024-12-31T23:59:59Z' }); // 生成可签名的SIWE字符串 const message = siweMsg.prepareMessage();
4. 执行签名
// 使用personal_sign完成签名,自动添加EIP-191前缀,和ethers的signMessage效果一致 const signature = await web3.eth.personal.sign(message, userAccount);
关键注意事项
web3.eth.personal.sign会自动为消息添加EIP-191规定的前缀(\x19Ethereum Signed Message:\n{messageLength}),这和ethers.js的signer.signMessage行为完全匹配,因此签名结果可以直接用于SIWE的后端验证流程。- 生成的nonce需要在前端存储(如localStorage),并在提交签名时一起发送给后端,用于防止重放攻击。
- 确保钱包已连接,且用户授权了账户访问权限。
内容的提问来源于stack exchange,提问作者Pavel Schoffer
相关产品推荐
相关产品推荐

