返回章节列表
第 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) return14 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 <button47 onClick={handleSignIn}48 className="px-4 py-2 bg-purple-500 rounded-lg"49 >50 {isSignedIn ? '已登录' : '使用以太坊登录'}51 </button>52 )53}