返回章节列表
第 06 章进阶

签名与身份验证

实现 SIWE 登录、消息签名和 EIP-712 类型化签名

5 课时2.5小时

概述

签名是 Web3 身份验证的核心。本章讲解各种签名方式和 SIWE 登录流程。

Sign-In with Ethereum (SIWE)

SIWE 是 Web3 原生的身份验证标准: 1. **生成挑战**: 服务端生成包含 nonce 的消息 2. **用户签名**: 用户使用钱包签名消息 3. **验证签名**: 服务端验证签名有效性 4. **建立会话**: 签名有效则创建用户会话

代码示例

SIWE 登录实现

完整的 SIWE 登录流程实现

typescript
1'use client'
2
3import { useAccount, useSignMessage } from 'wagmi'
4import { SiweMessage } from 'siwe'
5import { useState } from 'react'
6
7export function SignInWithEthereum() {
8 const { address, isConnected } = useAccount()
9 const { signMessageAsync } = useSignMessage()
10 const [isSignedIn, setIsSignedIn] = useState(false)
11
12 async function handleSignIn() {
13 if (!address) return
14
15 // 1. 创建 SIWE 消息
16 const message = new SiweMessage({
17 domain: window.location.host,
18 address,
19 statement: '登录 My DApp',
20 uri: window.location.origin,
21 version: '1',
22 chainId: 1,
23 nonce: Math.random().toString(36).slice(2), // 实际应从服务端获取
24 })
25
26 // 2. 用户签名
27 const signature = await signMessageAsync({
28 message: message.prepareMessage(),
29 })
30
31 // 3. 发送到服务端验证
32 const res = await fetch('/api/auth/verify', {
33 method: 'POST',
34 headers: { 'Content-Type': 'application/json' },
35 body: JSON.stringify({ message, signature }),
36 })
37
38 if (res.ok) {
39 setIsSignedIn(true)
40 }
41 }
42
43 if (!isConnected) return <p>请先连接钱包</p>
44
45 return (
46 <button
47 onClick={handleSignIn}
48 className="px-4 py-2 bg-purple-500 rounded-lg"
49 >
50 {isSignedIn ? '已登录' : '使用以太坊登录'}
51 </button>
52 )
53}

相关资源

SIWE 官网useSignMessage
上一章: 合约事件监听下一章: 账户抽象 SDK 集成