Zh:Authentication
Minecraft 1.6引入了一种全新的叫作Yggdrasil的认证方案,它彻底地取代了先前的认证系统。Mojang的其他游戏,Scrolls,同样也使用了该认证方法。Mojang曾经说过每个人都应使用此认证系统来进行自定义登录,但是永远不会从用户收集凭据。
Contents
请求格式
所有对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的那个相同
}
响应
若成功返回一个空负载。