Microsoft 登录流程

基本信息

属性 值
入口按钮 多人游戏界面 Oauth Login
主类 com.sintinium.oauth.login.MicrosoftLogin
HTTP 客户端 Apache HttpClientBuilder(连接/读取超时 30 秒)
本地回调端口 http://localhost:26669/relogin
OAuth Client ID 907a248d-3eb5-4d01-99d2-ff72d79c5eb1(mod 内置硬编码)
浏览器唤起 com.gtnewhorizon.gtnhlib.util.FilesUtil.openUri

功能

按 wiki.vg/Microsoft_Authentication_Scheme 规范实现标准 Microsoft OAuth 2.0 → Xbox Live → XSTS → Minecraft Services 六步授权,最终把拿到的 Minecraft access_token 包装成新的 net.minecraft.util.Session 注入 Minecraft.session 字段,实现不重启换号。

6 步链路

步 端点 作用 状态文字
1 https://login.live.com/oauth20_authorize.srf 启动本地 HTTP 服务并打开浏览器,引导用户登录 Check your browser(启动后)
2 https://login.live.com/oauth20_token.srf 用授权码换取 MS access_token / refresh_token Getting token from Microsoft
3 https://user.auth.xboxlive.com/user/authenticate 用 MS token 换 Xbox Live (XBL) JWT + user hash (UHS) Getting Xbox Live token
4 https://xsts.auth.xboxlive.com/xsts/authorize 用 XBL JWT 换 XSTS JWT Logging into Xbox Live
5 https://api.minecraftservices.com/authentication/login_with_xbox 用 XBL3.0 x=<UHS>;<XSTS> 换 Minecraft access_token Getting your Minecraft token
6 https://api.minecraftservices.com/minecraft/profile 用 Minecraft access_token 取用户名/UUID Loading your profile
- 内部 通过 会话与在线状态检测 注入 Session Logging you into Minecraft

OAuth 请求构造(步骤 1)

  • redirect_uri = http://localhost:26669/relogin
  • scope = XboxLive.signin%20offline_access
  • response_type = code
  • client_id 写死在源码中(见上)

授权完成后本地 HTTP 服务接收回调,提取 code=<value> 中的 value 作为 authorizeCode,然后停止 server。

OAuth 请求构造(步骤 2)

POST https://login.live.com/oauth20_token.srf
Content-type: application/x-www-form-urlencoded
client_id=<id>&scope=xboxlive.signin&code=<authorizeCode>
&grant_type=authorization_code&redirect_uri=http://localhost:26669/relogin

返回 access_token / refresh_token(注意 MsToken 内部实际只保存 accessToken)。

Xbox Live 请求(步骤 3)

POST https://user.auth.xboxlive.com/user/authenticate
{
  "Properties": {
    "AuthMethod": "RPS",
    "SiteName": "user.auth.xboxlive.com",
    "RpsTicket": "d=<MS access_token>"
  },
  "RelyingParty": "http://auth.xboxlive.com",
  "TokenType": "JWT"
}

响应 → Token (XBL JWT) + DisplayClaims.xui[0].uhs (用户哈希)。

XSTS 请求(步骤 4)

POST https://xsts.auth.xboxlive.com/xsts/authorize
{
  "Properties": {
    "SandboxId": "RETAIL",
    "UserTokens": ["<XBL JWT>"]
  },
  "RelyingParty": "rp://api.minecraftservices.com/",
  "TokenType": "JWT"
}

响应 → Token (XSTS JWT)。

Minecraft 登录(步骤 5)

POST https://api.minecraftservices.com/authentication/login_with_xbox
{
  "identityToken": "XBL3.0 x=<UHS>;<XSTS JWT>"
}

响应 → access_token。

Minecraft Profile(步骤 6)

GET https://api.minecraftservices.com/minecraft/profile
Authorization: Bearer <MC access_token>

响应 → name (用户名) + id (UUID,无连字符)。

取消机制

  • cancelLogin() 把 isCancelled = true
  • 每一步用 callIfNotCancelled(...) 包裹;当前步骤抛异常则 errorMsg 被赋值并返回 null,后续步骤短路

错误处理

  • 任一步骤失败 → 通过 org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace 把堆栈写入 errorMsg
  • 当前 GUI (LoginLoadingScreen) 不显示 errorMsg,只回传控制台 System.err.println
  • HTTP 实体为 null 时直接抛 RuntimeException("No entity!")(注释里留了 TODO 提醒换可读异常)

已知问题

  • MsToken 构造器丢弃 refreshToken(参数名取了但未保存)→ 刷新 token 流未实现,每次登录都走完整 OAuth 流程
  • 步骤 2 注释留有 TODO: Throw readable exception! —— 当前对网络错误的提示仅 RuntimeException("No entity!")
  • 端口 26669 写死,如果被占用则本地 HTTP 监听失败、登录卡死

相关条目