blob: e83cc35709f364c644b2776b7a79c464b222fab4 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
|
---
title: 身份验证
description: DropOut 中的 Microsoft OAuth 和离线身份验证
---
# 身份验证
DropOut 支持两种身份验证方法:Microsoft 账户(用于官方 Minecraft)和离线模式(用于测试和离线游玩)。
## Microsoft 身份验证
### 概述
DropOut 使用 **Device Code Flow** 进行 Microsoft 身份验证,具有以下特点:
- 无需重定向 URL(无需浏览器集成)
- 适用于任何拥有浏览器的设备
- 提供简单的基于代码的身份验证
- 完全符合 Microsoft OAuth 2.0 标准
### 身份验证流程
身份验证链包含多个步骤:
1. **Device Code** → 用户授权
2. **MS Token** → 访问令牌 + 刷新令牌
3. **Xbox Live** → Xbox 令牌 + UHS
4. **XSTS** → 安全令牌
5. **Minecraft** → 游戏访问令牌
6. **Profile** → 用户名 + UUID
#### 第 1 步:设备代码请求
1. 单击"使用 Microsoft 登录"
2. DropOut 从 Microsoft 请求设备代码
3. 您会收到:
- 用户代码(例如 `A1B2-C3D4`)
- 验证 URL(通常为 `https://microsoft.com/link`)
- 设备代码(内部使用)
#### 第 2 步:用户授权
1. 在任何浏览器中访问验证 URL
2. 输入用户代码
3. 使用 Microsoft 账户登录
4. 授权 DropOut 访问您的 Minecraft 个人资料
#### 第 3 步:令牌交换
- DropOut 轮询 Microsoft 检查授权完成
- 授权后接收访问令牌和刷新令牌
- 刷新令牌被存储以备将来登录使用
#### 第 4 步:Xbox Live 身份验证
- Microsoft 令牌被交换为 Xbox Live 令牌
- 检索用户哈希 (UHS) 用于下一步
#### 第 5 步:XSTS 授权
- Xbox Live 令牌被用来获取 XSTS 令牌
- 此令牌特定于 Minecraft 服务
#### 第 6 步:Minecraft 登录
- XSTS 令牌被交换为 Minecraft 访问令牌
- 使用端点:`/launcher/login`
#### 第 7 步:个人资料获取
- 检索您的 Minecraft 用户名
- 获取您的 UUID
- 检查您是否拥有 Minecraft
### 令牌管理
**访问令牌:**
- 短期有效(通常为 1 小时)
- 用于游戏身份验证
- 过期时自动刷新
**刷新令牌:**
- 长期有效(通常为 90 天)
- 安全存储在 `accounts.json` 中
- 用于获取新的访问令牌
**自动刷新:**
```rust
// Automatic refresh when token expires
if account.expires_at < current_time {
refresh_full_auth(&account).await?;
}
```
### 安全考虑
- 令牌存储在平台特定的应用数据目录中
- 所有 API 调用仅使用 HTTPS
- 不存储凭据(仅存储令牌)
- 需要 User-Agent 标头(绕过 MS WAF)
### Microsoft 登录故障排除
**"Device code expired"(设备代码已过期)**
- 代码在 15 分钟后过期
- 重新开始登录流程
**"Authorization pending"(授权待处理)**
- 在等待阶段很正常
- 在浏览器中完成授权
**"Invalid token"(无效令牌)**
- 令牌可能已过期
- 登出后重新登录
**"You don't own Minecraft"(您不拥有 Minecraft)**
- 验证您的 Microsoft 账户拥有 Minecraft Java Edition
- 在 https://www.minecraft.net/profile 检查
## 离线身份验证
### 概述
离线模式创建一个不需要互联网连接或 Microsoft 账户的本地账户。这对以下情况很有用:
- 测试和开发
- 无网络游玩
- LAN 多人游戏
- Mod 开发
### 创建离线账户
1. 在登录屏幕单击"离线模式"
2. 输入用户名(3-16 个字符)
3. 单击"创建账户"
### 工作原理
**UUID 生成:**
```rust
// Deterministic UUID v3 from username
let uuid = generate_offline_uuid(&username);
```
- 使用 UUID v3(基于命名空间)
- 确定性:相同的用户名 = 相同的 UUID
- 无需网络请求
**身份验证:**
- 返回 `"null"` 作为访问令牌
- Minecraft 在离线模式下接受空令牌
- 用户名和 UUID 本地存储
### 限制
- 无法加入在线服务器
- 不支持皮肤
- 不支持披风
- 无法使用 Microsoft 账户功能
### 用例
**开发:**
```bash
# Testing mod development
cargo tauri dev
# Use offline mode to test quickly
```
**LAN 游玩:**
- 无需身份验证即可加入 LAN 世界
- 托管 LAN 世界
**离线游玩:**
- 单人游戏无需网络
- 无需身份验证
## 账户管理
### 切换账户
目前 DropOut 一次只支持一个活跃账户。多账户支持正在规划中。
**切换账户的步骤:**
1. 登出当前账户
2. 使用新账户登录
### 账户存储
账户存储在 `accounts.json` 中:
```json
{
"current_account_id": "uuid-here",
"accounts": [
{
"id": "uuid",
"type": "Microsoft",
"username": "PlayerName",
"access_token": "...",
"refresh_token": "...",
"expires_at": 1234567890
}
]
}
```
### 删除账户
删除账户的步骤:
1. 打开设置
2. 导航到账户
3. 单击"登出"
4. 或手动删除 `accounts.json`
## API 参考
### Tauri 命令
**启动 Microsoft 登录:**
```typescript
const { user_code, verification_uri } = await invoke('start_microsoft_login');
```
**完成 Microsoft 登录:**
```typescript
const account = await invoke('complete_microsoft_login', { deviceCode });
```
**离线登录:**
```typescript
const account = await invoke('offline_login', { username: 'Player' });
```
**登出:**
```typescript
await invoke('logout');
```
**获取当前账户:**
```typescript
const account = await invoke('get_current_account');
```
### 事件
**身份验证状态:**
```typescript
listen('auth-status', (event) => {
console.log(event.payload); // "logged_in" | "logged_out"
});
```
## 最佳实践
### 对于玩家
1. **对官方服务器使用 Microsoft 账户**
2. **保护令牌安全** - 不要分享 accounts.json
3. **定期刷新令牌** - 通过登录来刷新
4. **仅在测试时使用离线模式**
### 对于开发者
1. **优雅地处理令牌过期**
2. **为网络故障实现重试逻辑**
3. **缓存账户数据** 以减少 API 调用
4. **在游戏启动前验证令牌**
## 未来增强
- **多账户支持**:轻松在账户之间切换
- **账户配置文件**:保存每个账户的设置
- **自动登录**:记住最后一个账户
- **令牌加密**:为存储的令牌增强安全性
|