Minecraft使用Microsoft账号登录游戏具体流程

Microsoft 身份验证

有关 API 文档,请参阅 Mojang API

从2022年7月开始,旧版Mojang账号将无法登录游戏,需要使用Microsoft账号来登录。

使用微软账号登录Minecraft需要进行前四个步骤来获取Minecraft访问令牌。

获取Microsoft令牌

在开始之前,你需要创建Microsoft Azure应用程序来获取一个OAuth 2.0 客户端 ID,然后你就可以使用授权代码流设备代码流隐式授权流等方式来获取Microsoft令牌。

无论使用何种方式,你都需要在scope参数中包含XboxLive.signin,否则在下一个步骤将会报错,并且错误信息并不会给你任何帮助!

根据此文章所述,创建的Microsoft Azure应用程序必须在此表单申请可以调用Minecraft API的权限,如果应用程序没有被授权,将会在访问api.minecraftservices.com时返回403。

以下为使用隐式授权流获取令牌的方法:

使用浏览器访问https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id=<客户端ID>&response_type=token&redirect_uri=<回调URI>&scope=XboxLive.signin offline_access&state=<可选状态值>&response_mode=fragment

在打开的页面登录Microsoft账户,登录成功会回跳转回调URI,例如URI为https://127.0.0.1,跳转的页面为https://127.0.0.1/#access_token=<Microsoft令牌>&token_type=bearer&expires_in=3600&scope=XboxLive.signin&state=<可选状态值>

你需要手动保存或编写自定义网页提取Microsoft令牌来进行下一步骤。

其他方式获取Microsoft令牌请阅读Microsoft官方文档。

进行XBL身份验证(获取Xbox Live令牌)

进行此步骤的前提是已经获得Microsoft令牌。

发送如下请求:

POST https://user.auth.xboxlive.com/user/authenticate
Content-Type: application/json
Accept: application/json
{
    "Properties": {
        "AuthMethod": "RPS",
        "SiteName": "user.auth.xboxlive.com",
        "RpsTicket": "d=<Microsoft令牌>" // 在上一步中获取的令牌,请保留前缀d=
    },
    "RelyingParty": "http://auth.xboxlive.com",
    "TokenType": "JWT"
}

你需要设置Content-Type: application/jsonAccept: application/json,并且确保你的 SSL 实现支持 SSL 重新协商,否则就会出现错误。

返回如下:

{
    "IssueInstant": "2020-12-07T19:52:08.4463796Z",
    "NotAfter": "2020-12-21T19:52:08.4463796Z",
    "Token": "token", // XBL令牌
    "DisplayClaims": {
        "xui": [
            {
                "uhs": "userhash" // 用户哈希值
            }
        ]
    }
}

注意:你需要保存其中的XBL令牌和用户哈希值

获取XSTS令牌

获取XBL令牌后,我们需要用此令牌来获取XSTS令牌

发送如下请求:

POST https://xsts.auth.xboxlive.com/xsts/authorize
Content-Type: application/json
Accept: application/json
{
    "Properties": {
        "SandboxId": "RETAIL",
        "UserTokens": [
            "xbl_token" // XBL令牌
        ]
    },
    "RelyingParty": "rp://api.minecraftservices.com/",
    "TokenType": "JWT"
}

如需获取用于Bedrock Realms API的XSTS令牌 , 需提交:

{
    "Properties": {
        "SandboxId": "RETAIL",
        "UserTokens": [
            "xbl_token" // XBL令牌
        ]
    },
    "RelyingParty": "https://pocket.realms.minecraft.net/",
    "TokenType": "JWT"
}

返回如下:

{
    "IssueInstant": "2020-12-07T19:52:09.2345095Z",
    "NotAfter": "2020-12-08T11:52:09.2345095Z",
    "Token": "token", // XSTS令牌
    "DisplayClaims": {
        "xui": [
            {
                "uhs": "userhash" // 用户哈希值,应与上一步骤中的用户哈希值相同
            }
        ]
    }
}

可能会返回401报错:

{
    "Identity": "0",
    "XErr": 2148916238,
    "Message": "",
    "Redirect": "https://start.ui.xboxlive.com/AddChildToFamily"
}

Redirect参数通常无法在浏览器中正常跳转,该功能主要针对Xbox主机设计

XErr代码解析:

2148916227: 账号已被Xbox封禁
2148916233: 账号未注册Xbox。需通过minecraft.net登录创建(注:已购买Minecraft的微软账户应已完成此步骤)
2148916235: 账号所属国家/地区不支持Xbox Live服务
2148916236: 需在Xbox页面完成成人验证(韩国)
2148916237: 需在Xbox页面完成成人验证(韩国)
2148916238: 未成年账户(未满18岁),必须由成人账户添加到家庭组才能继续。此错误通常仅在使用自定义Azure应用时出现,官方Minecraft启动器客户端ID不会触发此限制
2148916262: 未知错误(很少)

至此即可完成 Bedrock Realms 的验证, 它直接使用 XSTS令牌 ,而不是使用单独的身份验证方案

获取Minecraft访问令牌

至此,我们可以与Minecraft验证服务器进行交互,从此步骤开始,你需要拥有调用Minecraft API的权限,如没有权限,将会返回403

发送如下请求:

POST https://api.minecraftservices.com/authentication/login_with_xbox
Content-Type: application/json
Accept: application/json
{
    "identityToken": "XBL3.0 x=<用户哈希值>;<XSTS令牌>"
}

返回如下

{
    "username": "some uuid", // 非账户真实UUID
    "roles": [],
    "access_token": "minecraft access token", // jwt,即传统MC令牌
    "token_type": "Bearer",
    "expires_in": 86400
}

保存Minecraft令牌,此令牌可用于启动游戏

以上步骤仅需一个普通的Microsoft账号即可完成,并不会验证是否购买游戏

验证是否购买游戏

使用Minecraft令牌来验证是否购买游戏

发送:

GET https://api.minecraftservices.com/entitlements/mcstore
Authorization: Bearer <Minecraft令牌>

如果该账户购买了游戏,将返回:

{
    "items": [
        {
            "name": "product_minecraft",
            "signature": "jwt sig"
        },
        {
            "name": "game_minecraft",
            "signature": "jwt sig"
        }
    ],
    "signature": "jwt sig",
    "keyId": "1"
}

如果账户未拥有游戏,items将为空:

{
    "items": [],
    "signature": "jwt sig",
    "keyId": "1"
}

注意,Xbox Game Pass用户在技术上并不拥有游戏,虽然能正常生成Minecraft角色档案,但此处仍返回空

注意,必须使用 Mojang 官方公钥验证签名,以确保响应确实来自合法服务器,而非伪造或篡改的数据:

-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtz7jy4jRH3psj5AbVS6W
NHjniqlr/f5JDly2M8OKGK81nPEq765tJuSILOWrC3KQRvHJIhf84+ekMGH7iGlO
4DPGDVb6hBGoMMBhCq2jkBjuJ7fVi3oOxy5EsA/IQqa69e55ugM+GJKUndLyHeNn
X6RzRzDT4tX/i68WJikwL8rR8Jq49aVJlIEFT6F+1rDQdU2qcpfT04CBYLM5gMxE
fWRl6u1PNQixz8vSOv8pA6hB2DU8Y08VvbK7X2ls+BiS3wqqj3nyVWqoxrwVKiXR
kIqIyIAedYDFSaIq5vbmnVtIonWQPeug4/0spLQoWnTUpXRZe2/+uAKN1RY9mmaB
pRFV/Osz3PDOoICGb5AZ0asLFf/qEvGJ+di6Ltt8/aaoBuVw+7fnTw2BhkhSq1S/
va6LxHZGXE9wsLj4CN8mZXHfwVD9QG0VNQTUgEGZ4ngf7+0u30p7mPt5sYy3H+Fm
sWXqFZn55pecmrgNLqtETPWMNpWc2fJu/qqnxE9o2tBGy/MqJiw3iLYxf7U+4le4
jM49AUKrO16bD1rdFwyVuNaTefObKjEMTX9gyVUF6o7oDEItp5NHxFm3CqnQRmch
HsMs+NxEnN4E9a8PDB23b4yjKOQ9VHDxBxuaZJU60GBCIOF9tslb7OAkheSJx5Xy
EYblHbogFGPRFU++NrSQRX0CAwEAAQ==
-----END PUBLIC KEY-----

更多细节请查阅 JWT 标准

如果公钥发生变化,可以从启动器库中提取:

strings ~/.minecraft/launcher/liblauncher.so > launcher-strings.txt

创建的文件launcher-strings.txt 将包含两个公钥字符串,以 -----BEGIN PUBLIC KEY----- 开始,以 -----END PUBLIC KEY-----结束

第一个密钥用于校验 Minecraft 服务端返回的 JWT 令牌签名, 第二个密钥的用途到目前为止未知

获取玩家信息

GET https://api.minecraftservices.com/minecraft/profile
Authorization: Bearer <Minecraft令牌>

返回如下:

{
    "id": "986dec87b7ec47ff89ff033fdb95c4b5", // 用户的UUID
    "name": "HowDoesAuthWork", // 账户的Minecraft用户名
    "skins": [
        {
            "id": "6a6e65e5-76dd-4c3c-a625-162924514568",
            "state": "ACTIVE",
            "url": "http://textures.minecraft.net/texture/1a4af718455d4aab528e7a61f86fa25e6a369d1768dcb13f7df319a713eb810b",
            "variant": "CLASSIC",
            "alias": "STEVE"
        }
    ],
    "capes": [
        {
            "id": "5af20372-79e0-4e1f-80f8-6bd8e3135995",
            "state": "ACTIVE",
            "url": "http://textures.minecraft.net/texture/2340c0e03dd24a11b15a8b33c2a7e9e32abb2051b2481d0ba7defd635ca7a933",
            "alias": "Migrator"
        }
    ]
}

请求失败将返回:

{
    "path": "/minecraft/profile",
    "error": "NOT_FOUND",
    "errorMessage": "The server has not found anything matching the request URI"
}

没有登录过Minecraft启动器的Xbox Game Pass用户将不会返回配置文件,需要在激活Xbox Game Pass后登录一次新版Minecraft启动器来激活Minecraft档案

至此,现在已经拥有启动游戏所需的所有数据(Minecraft访问令牌、用户名和UUID)了

开发例子:

  • minecraft_auth.py: 模拟官方启动器的认证方式(即授权代码流)并支持刷新令牌请求.
    一个完整的 Kotlin 实现(使用设备代码流)可以在这里找到.
  • 基于设备代码流的完整Java命令行封装实现参见此项目
    一个基于 Java 的简易实现示例(使用 JavaFX 及其 WebView 组件)可在此处查看.
  • 一个功能完整的 Java 库(支持 4 种登录流程)可在此处获取.
  • 一个Go语言的实现可以在这里找到.
  • 一个JS实现可以在这里找到,另一个使用JS/TS的实现参见此处.
  • 一个Python的实现可以在这里找到.
  • 一个Rust语言的实现可以在这里找到.
  • 一个支持 JVM 和 JS 平台的 Kotlin 库可在此处获取.
  • 一个使用WebView和MSAL.NET(微软身份验证库.NET版)的C#库可以在这里找到
  • 一个 Rust 库可以在这里找到.
  • 一个PHP库可以在这里找到.
  • 一个易语言实现可以在这里找到.
posted @ 2025-05-02 19:41  是半山哟  阅读(595)  评论(0)    收藏  举报