Skip to content

Commit 74fb371

Browse files
committed
Add study notes for 2025-08-21
1 parent e902768 commit 74fb371

1 file changed

Lines changed: 150 additions & 0 deletions

File tree

Loop-YY.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)