--- 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. **在游戏启动前验证令牌** ## 未来增强 - **多账户支持**:轻松在账户之间切换 - **账户配置文件**:保存每个账户的设置 - **自动登录**:记住最后一个账户 - **令牌加密**:为存储的令牌增强安全性