@@ -15,6 +15,156 @@ Web2从业者,转型Web3中
1515## Notes
1616
1717<!-- Content_START -->
18+ # 2025-08-21
19+
20+ # MetaMask 一键登录设计学习笔记
21+
22+ ## 学习目标
23+ - 掌握基于 MetaMask 的去中心化登录系统的实现原理和流程。
24+ - 学会使用 Vue 和 CloudFlare Worker 实现前端和后端的相关功能。
25+
26+ ## 一、登录流程概述
27+ 1 . ** 前端获取用户以太坊账户地址** :通过 MetaMask 的 ` eth_requestAccounts ` API 获取用户的以太坊账户地址。
28+ 2 . ** 后端生成签名内容** :后端生成一个随机的 ` nonces ` 值,并将其与用户的以太坊地址存储在 CloudFlare KV 中。
29+ 3 . ** 前端请求签名内容** :前端向后端发送 ` PUT ` 请求,获取 ` nonces ` 。
30+ 4 . ** 用户签名** :前端使用 MetaMask 的 ` signTypedData_v4 ` API,让用户对包含 ` nonces ` 的数据进行签名。
31+ 5 . ** 后端验证签名** :前端将签名结果和以太坊地址发送到后端,后端使用 ` recoverTypedSignature ` 验证签名是否与地址匹配。
32+ 6 . ** 生成 JWT 凭证** :如果验证通过,后端生成 JWT 作为登录凭证并返回给前端。
33+
34+ ## 二、前端实现
35+
36+ ### (一)检测 MetaMask 支持
37+ - 通过 ` window.ethereum.isMetaMask ` 检测用户是否安装了 MetaMask 插件。
38+ - 如果未安装,则不显示登录按钮。
39+
40+ ### (二)获取以太坊账户地址
41+ - 使用 ` window.ethereum.request ` 方法获取用户的以太坊账户地址。
42+ - 示例代码:
43+ ``` javascript
44+ window .ethereum .request ({ method: ' eth_requestAccounts' }).then (
45+ accounts => {
46+ this .ethAccount = accounts[0 ]
47+ console .log (this .ethAccount );
48+ }
49+ )
50+ ```
51+
52+ ### (三)请求 ` nonces `
53+ - 通过 ` axios.put ` 向后端发送请求,获取 ` nonces ` 。
54+ - 示例代码:
55+ ``` javascript
56+ axios .put (" http://localhost:8787" , { " from" : this .ethAccount }).then (res => {
57+ this .nonces = res .data .nonces ;
58+ }).then (() => {
59+ console .log (this .nonces );
60+ })
61+ ```
62+
63+ ### (四)签名数据结构
64+ - 定义了符合 EIP-712 标准的签名数据结构,包括 ` domain ` 、` message ` 、` primaryType ` 和 ` types ` 。
65+ - 示例代码:
66+ ``` javascript
67+ const msgParams = {
68+ domain: {
69+ chainId: window .ethereum .chainId ,
70+ name: ' Login' ,
71+ version: ' 1'
72+ },
73+ message: {
74+ contents: ' Login' ,
75+ nonces: this .nonces ,
76+ },
77+ primaryType: ' Login' ,
78+ types: {
79+ EIP712Domain: [
80+ { name: ' name' , type: ' string' },
81+ { name: ' version' , type: ' string' },
82+ { name: ' chainId' , type: ' uint256' },
83+ ],
84+ Login: [
85+ { name: ' contents' , type: ' string' },
86+ { name: ' nonces' , type: ' uint256' },
87+ ],
88+ },
89+ };
90+ ```
91+
92+ ### (五)签名操作
93+ - 调用 ` ethereum.request ` 方法,使用 ` eth_signTypedData_v4 ` 对数据进行签名。
94+ - 示例代码:
95+ ``` javascript
96+ ethereum .request ({
97+ method: ' eth_signTypedData_v4' ,
98+ params: [from, JSON .stringify (msgParams)],
99+ }).then ((res ) => {
100+ this .sign = res;
101+ console .log (res);
102+ })
103+ ```
104+
105+ ### (六)回传签名结果
106+ - 将签名结果、以太坊地址和链 ID 通过 ` axios.post ` 发送到后端。
107+ - 示例代码:
108+ ``` javascript
109+ axios .post (" http://localhost:8787" , {
110+ " chainId" : window .ethereum .chainId ,
111+ " from" : this .ethAccount ,
112+ " signature" : this .sign
113+ }).then (
114+ res => {
115+ if (res .data .verify ) {
116+ localStorage .setItem (" token" , res .data .token );
117+ localStorage .setItem (" expire" , Date .now () + 3600000 );
118+ localStorage .setItem (" userName" , this .ethAccount );
119+ console .log (" 登录成功" );
120+ } else {
121+ console .log (" 登录失败,请重新登录" );
122+ }
123+ }
124+ )
125+ ```
126+
127+ ## 三、后端实现
128+
129+ ### (一)环境搭建
130+ - 使用 CloudFlare Wrangler 创建开发环境,并绑定 KV 数据库。
131+ - 示例代码:
132+ ``` bash
133+ wrangler kv:namespace create web3login
134+ ```
135+
136+ ### (二)生成 ` nonces `
137+ - 后端接收前端发送的以太坊地址,生成随机 ` nonces ` 并存储在 KV 中。
138+ - 示例代码:
139+ ``` javascript
140+ let nonces = Math .floor (Math .random () * 1000000 )
141+ await loginKV .put (key, nonces, { expirationTtl: 120 })
142+ ```
143+
144+ ### (三)验证签名
145+ - 使用 ` recoverTypedSignature ` 函数验证签名是否与用户地址匹配。
146+ - 示例代码:
147+ ``` javascript
148+ const recoveredAddr = recoverTypedSignature ({
149+ data: msgParams,
150+ signature: signature,
151+ version: version,
152+ });
153+ ```
154+
155+ ### (四)生成 JWT
156+ - 如果验证通过,使用 ` jose ` 库生成 JWT 作为登录凭证。
157+ - 示例代码:
158+ ``` javascript
159+ const tokenLogin = await new SignJWT ({ " user_id" : from })
160+ .setProtectedHeader ({ alg: ' HS256' , typ: ' JWT' })
161+ .setExpirationTime (' 1h' )
162+ .sign (Buffer .from (SECRET_KEY , " utf8" ));
163+ ```
164+
165+ ## 四、总结
166+ 通过上述学习,我掌握了基于 MetaMask 的去中心化登录系统的实现原理和流程。前端使用 Vue 框架实现用户交互,后端使用 CloudFlare Worker 和 KV 服务实现签名内容的生成和验证。整个系统利用以太坊的非对称加密特性,通过用户对特定数据的签名来验证身份,并生成 JWT 作为登录凭证。这种去中心化的登录方式更加安全且符合 Web3 的理念。
167+
18168# 2025-08-18
19169
20170---
0 commit comments