ZH:Authentication

From wiki.vg
Revision as of 15:13, 30 September 2019 by Kaniol (talk | contribs) (Created page with "Minecraft 1.6引入了一种全新的叫作'''Yggdrasil'''的认证方案,它彻底地取代了先前的认证系统。Mojang的其他游戏,Scrolls,...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Minecraft 1.6引入了一种全新的叫作Yggdrasil的认证方案,它彻底地取代了先前的认证系统。Mojang的其他游戏,Scrolls,同样也使用了该认证方法。Mojang曾经说过每个人都应使用此认证系统来进行自定义登录,但是永远不会从用户收集凭据

请求格式

所有对Yggdrasil的请求都会发送到以下服务器:

https://authserver.mojang.com

此外,它们应满足以下规则:

  • POST请求
  • Content-Type头设置为application/json
  • 以包含JSON编码的字典作为负载

如果请求成功,服务器将响应:

  • 状态码200
  • 根据以下规范使用JSON编码的字典

但如果请求失败,服务器会响应:

{
    "error": "Short description of the error",
    "errorMessage": "Longer description which can be shown to the user",
    "cause": "Cause of the error" // 可选的
}

错误

这些是可能遇到的一些错误:

Error Cause Error message Notes
Method Not Allowed The method specified in the request is not allowed for the resource identified by the request URI Something other than a POST request was received.
Not Found The server has not found anything matching the request URI Non-existing endpoint was called.
ForbiddenOperationException UserMigratedException Invalid credentials. Account migrated, use e-mail as username.
ForbiddenOperationException Invalid credentials. Invalid username or password.
ForbiddenOperationException Invalid credentials. Too many login attempts with this username recently (see /authenticate). Note that username and password may still be valid!
ForbiddenOperationException Invalid token. accessToken was invalid.
IllegalArgumentException Access token already has a profile assigned. Selecting profiles isn't implemented yet.
IllegalArgumentException credentials is null Username/password was not submitted.
IllegalArgumentException Invalid salt version ???
Unsupported Media Type The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method Data was not submitted as application/json

认证

通过密码认证用户。

后缀

/authenticate

负载

{
    "agent": {                              // 默认为Minecraft
        "name": "Minecraft",                // 对于Mojang的其他游戏Scrolls,则应该使用"Scrolls"
        "version": 1                        // 以后的原版客户端
                                            // 可能会增加该数字
    },
    "username": "mojang account name",      // 可以是电子邮箱地址或
                                            // 玩家名称(对于为迁移的账号)
    "password": "mojang account password",
    "clientToken": "client identifier",     // 可选的
    "requestUser": true                     // 可选的,默认为false,若为true则将user对象加入到响应中
}

clientToken应该是一个随机生成的标识符而且必须每次请求都是相同的。原版启动器会在第一次运行时生成一个随机的(v4)UUID并保存,在后续每次请求中复用它。如果省略,那么服务器会生成一个基于Java的UUID.toString()的随机令牌,它应该由客户端保存下来。然而这也会使用户之前在所有客户端上获取的accessToken失效。

响应

{
    "accessToken": "random access token",      // 十六进制
    "clientToken": "client identifier",        // 与接收到的相同
    "availableProfiles": [                     // 仅在接收到agent字段时出现
        {
            "id": "profile identifier",        // 十六进制
            "name": "player name",
            "legacy": true or false            // 事实上它仅为true时出现。默认为false。
        }
    ],
    "selectedProfile": {                       // 仅在接收到agent字段时出现
        "id": "uuid without dashes",
        "name": "player name",
        "legacy": true or false
    },
    "user": {                                  // 仅在请求负载中的requestUser为true出现
        "id": "user identifier",               // 十六进制
        "properties": [
            {
                "name": "preferredLanguage",   // 也许不会对所有账号显示
                "value": "en"                  // Java locale格式 (https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#toString--)
            },
            {
                "name": "twitch_access_token", // 仅在关联twitch账号时出现(见https://account.mojang.com/me/settings)
                "value": "twitch oauth token"  // OAuth 2.0令牌,字母+数字,如https://api.twitch.tv/kraken?oauth_token=[...]
                                               // Twitch API的文档:https://github.com/justintv/Twitch-API
            }
        ]
    }
}

注意:如果用户希望能在他们的电脑上保存登录状态,那么强烈建议应该存储accessToken而不是密码本身。

当前每个账号只拥有一个档案,一个账号拥有多个档案还在未来计划中。如果用户尝试登入一个没有附加Minecraft许可的Mojang账号,那么认证将会成功,但是响应将不包含selectedProfile字段,而且availableProfiles数组也是空的。

有一些实例曾观察到Mojang对于旧版账号失败的刷新请求返回了一个平坦的null。还不清楚什么实际错误绑定了这个空响应,而且它极为罕见,但作为实现应该注意对该响应的空输出。

这个后缀是严格速率限制的:短时间内同一账号的多次/authenticate请求(例如在几秒内3次请求),即使密码正确也会导致一个Invalid credentials.响应。该错误会在几秒后被清除。

刷新

刷新一个有效的accessToken。它可以用于在游戏会话间保持登录状态,这优于在文件中保存用户的密码(见lastlogin)。

后缀

/refresh

负载

{
    "accessToken": "valid accessToken",
    "clientToken": "client identifier",  // 这需要与第一处用来获取
                                         // accessToken的那个相同
    "selectedProfile": {                 // 可选的,发送它将导致错误
        "id": "profile identifier",      // 十六进制
        "name": "player name"
    },
    "requestUser": true                  // 可选的,默认为false,若为true则将user对象加入到响应中
}

注意:提供的accessToken将失效。

响应

{
    "accessToken": "random access token",      // 十六进制
    "clientToken": "client identifier",        // 与接收到的相同
    "selectedProfile": {
        "id": "profile identifier",            // 十六进制
        "name": "player name"
    },
    "user": {                                  // 仅在请求负载中的requestUser为true出现
        "id": "user identifier",               // 十六进制
        "properties": [
            {
                "name": "preferredLanguage",   // 也许不会对所有账号显示
                "value": "en"                  // Java locale格式(https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#toString--)
            },
            {
                "name": "twitch_access_token", // 仅在关联twitch账号时出现(见https://account.mojang.com/me/settings)
                "value": "twitch oauth token"  // OAuth 2.0令牌,字母+数字,如https://api.twitch.tv/kraken?oauth_token=[...]
                                               // Twitch API的文档:https://github.com/justintv/Twitch-API
            }
        ]
    }
}

验证

检查accessToken是否可用于Minecraft服务器的认证。Minecraft启动器(自1.6.13版本起)会在启动器调用此后缀来验证保存的令牌是否仍然可用,并会在返回错误时调用/refresh

请注意accessToken可能会不可用与Minecraft服务器的认证,而对于/refresh来说足够可用。这主要会发生在一个人使用了另一个客户端(如在别的PC上使用相同的帐号游玩了Minecraft)。看起来只有给定帐号最新获得的accessToken才能可靠地用于认证(第二新的令牌看起来也仍然有效,但请不要依赖它)。

/validate可以在有或没有clientToken时调用。如果提供了clientToken,它应当与获取accessToken的那个相匹配。Minecraft启动器会向/validate发送clientToken

后缀

/validate

负载

{
    "accessToken": "valid accessToken",
    "clientToken": "associated clientToken" // 可选的,见上
}

响应

若成功返回空响应(204 No Content),否则返回错误JSON和状态码403 Forbidden

登出

使用帐号的用户名和密码使accessToken失效。

后缀

/signout

负载

{
    "username": "mojang account name",
    "password": "mojang account password"
}

响应

若成功返回一个空负载。

使失效

使用client/access令牌对使accessToken失效。

后缀

/invalidate

负载

{
    "accessToken": "valid accessToken",
    "clientToken": "client identifier"   // 这需要与第一处用来获取
                                         // accessToken的那个相同
}

响应

若成功返回一个空负载。

加入服务器

协议加密#认证