EVE Online 国服 ESI 登录方法记录

说明

通过ESI,我们可以利用HTTP请求的方式获取和改变游戏内的内容,也可以通过其OAuth2身份认证实现基于EVE账号的第三方登录,类似于你在某个非Github的网站使用Github账号登录。

OAuth2

现在许多第三方登录方式的实现其实都是OAuth,全称是Open Authorization,一种开放授权协议,允许第三方应用程序使用资源所有者的凭据获得对资源有限访问权限。

使用场景比如,你自己写了一个Github代码仓库分析的网站,这固然需要Github代码仓库的内容,难道要用户自己从Github克隆到电脑上然后又上传给你的网站?这太麻烦了。使用Github提供的OAuth,并且索要仓库的访问、修改权限(Github的话默认给了),在登录你的网站时通过Github账号登录,你的网站就有了访问该用户Github仓库的能力。

也可以看看某百科的例子:

如果一个用户需要两项服务:一项服务是图片在线存储服务A,另一个是图片在线打印服务B。由于服务A与服务B是由两家不同的服务提供商提供的,所以用户在这两家服务提供商的网站上各自注册了两个用户,假设这两个用户名各不相同,密码也各不相同。当用户要使用服务B打印存储在服务A上的图片时,用户该如何处理。方法一:用户可能先将待打印的图片从服务A上下载下来并上传到服务B上打印,这种方式安全但处理比较繁琐,效率低下;方法二:用户将在服务A上注册的用户名与密码提供给服务B,服务B使用用户的帐号再去服务A处下载待打印的图片,这种方式效率是提高了,但是安全性大大降低了,服务B可以使用用户的用户名与密码去服务A上查看甚至篡改用户的资源。OAuth就可以实现在服务B上使用服务A的账号密码登录(账号密码判断也是由A进行),用户确认后服务B就可以访问服务A里的照片。

OAuth的具体概念和使用方法、四种授权模式别人的文章写得很清楚,暂时无法超越,故请读者自行学习。(后面会填坑)

EVE ESI 认证

网易官方没有放出申请OAuth接口(申请Application,以获得client_id和client_secret)的地方,但是击杀榜网站和商人助手等依旧能够调用ESI,原因是网易的ESI(EVE Swagger Interface网页)其实也是一个Application,他的client_id为bc90aa496a404724a93f41b4f4e97761,用它就行。

Implicit模式

隐式授权是为了兼顾到在浏览器中用诸如JavaScript的脚本语言实现的客户端而优化的简化授权代码流程。在隐式授权流程中,不是发给客户端一个授权码,而是直接发给客户端一个访问令牌,而且不会对客户端进行认证。隐式授权提高了一些客户端(比如基于浏览器实现的客户端)的响应能力和效率,因为它减少了获得访问令牌所需的往返次数。

使用Implicit模式通过认证直接获取到access_token,但是这个Token通常只有20分钟的有效期。

怎么做

需要用户在浏览器中打开:

1
GET https://login.evepc.163.com/v2/oauth/authorize

并携带Query参数:

参数名称 说明
response_type 必填,授权模式,隐式授权填token
client_id 必填,OAuth的客户端ID,此处填官方的bc90aa496a404724a93f41b4f4e97761
redirect_uri 必填,表示授权成功后跳转并携带Token的URI,这里只能填https://esi.evepc.163.com/ui/oauth2-redirect.html
state 必填,表示客户端的当前状态,可以指定任意值,授权成功后将原样返回用以校验
scope 选填但不填没意义,表示申请的权限范围,不可超过4项,权限具体权限见后文
realm 必填,不知道干嘛的,随便写点什么
device_id 同上

上一步的请求执行后会跳转到网易账号的登录网页,登录完成后会选择EVE角色,选择完成后会跳转到设置的redirect_uri,并且地址栏中带有Token,这个URI长这样:

1
https://esi.evepc.163.com/ui/oauth2-redirect.html#access_token={你要的Token}&expires_in={过期时间}&state={原样返回的状态码}

Token中的参数如下:

参数名称 说明
access_token 权限令牌,使用它可以读取所选游戏人物对应的私密内容
expires_in 过期时间,单位为秒,一般为20分钟
state 将上面请求的state原封不动返回

你只需要让用户复制浏览器中地址栏这段URI,然后分析提取出AccessToken即可。

Authorization模式

授权码是授权服务器用来获取并作为客户端和资源所有者之间的中介。代替直接向资源所有者请求授权,客户端定向资源所有者到一个授权服务器,授权服务器反过来指导资源所有者将授权码返回给客户端。在将授权码返回给客户端之前,授权服务器对资源所有者进行身份验证并获得授权。因为资源所有者只对授权服务器进行身份验证,所以资源所有者的凭据永远不会与客户机共享。

流程比较复杂,但是因为拿到了refresh_token可以永久获取access_token(但refresh_token泄露等于密码泄露,只能用户去官网解除授权)。

第一步

需要用户在浏览器中打开:

1
GET https://login.evepc.163.com/v2/oauth/authorize

并携带Query参数:

参数名称 说明
response_type 必填,授权模式,授权码模式填code
client_id 必填,OAuth的客户端ID,此处填官方的bc90aa496a404724a93f41b4f4e97761
redirect_uri 必填,表示授权成功后跳转并携带Token的URI,这里只能填https://esi.evepc.163.com/ui/oauth2-redirect.html
state 必填,表示客户端的当前状态,可以指定任意值,授权成功后将原样返回用以校验
scope 选填但不填没意义,表示申请的权限范围,不可超过4项,权限具体权限见后文
realm 必填,不知道干嘛的,随便写点什么
device_id 同上

和Implicit模式只有response_type不同

同Implicit模式,选择完成后会跳转到设置的redirect_uri,并带以下参数:

参数名称 说明
code 表示授权码、有效期应该很短,通常为10分钟,且只能使用该码一次
state 将上面请求的state原封不动返回

URI长这样:

1
https://esi.evepc.163.com/ui/oauth2-redirect.html?code={授权码}&state={原样返回的状态码}

从URI拿到code,进入下一步。

第二步

在自己的应用,随便用什么请求工具,发送一个POST请求到:

1
POST https://login.evepc.163.com/v2/oauth/token

并在请求Body中以x-www-form-urlencoded形式传递以下参数:

参数名称 说明
grant_type 必填,表示获取类型,此处的值为authorization_code
client_id 必填,还是那个ID
redirect_uri 必填,还是那个URI
code 必填,上一步获取到的code,授权码

其他Body格式没尝试过

会响应application/json; charset=utf-8,内容如下:

1
2
3
4
5
6
{
"access_token": "xxxx",
"expires_in": 1199,
"token_type": "Bearer",
"refresh_token": "xxxx"
}
参数名称 说明
access_token 和隐式模式相同的只有20分钟的Token
expires_in 过期时间,通常是20分钟
refresh_token 一个永久有效的、用于重新获取access_token的token

获取/刷新access_token

第二步中拿到的access_token仍然是会过期的,关键是储存好refresh_token,在用户使用时用它重复获取access_token。

步骤类似第二步,在自己的应用发送一个POST请求到:

1
POST https://login.evepc.163.com/v2/oauth/token

并在请求Body中以x-www-form-urlencoded形式传递以下参数:

参数名称 说明
grant_type 必填,表示获取类型,此处的值为refresh_token
client_id 必填,还是那个ID
refresh_token 必填,上一步获取到的refresh_token

权限

不是所有东西都能通过ESI获取的

  1. 钱包:包括转账记录、交易记录(没错,就是空间站右键交易)、余额、市场买卖、忠诚点等
    • 授权项目例子:esi-wallet.read_character_wallet.v1、esi-wallet.read_character_wallet.v1、esi-characters.read_loyalty.v1
    • 无法读取的有:LP消费记录、LP收益来源(可以通过消息列表间接查询到2022.11.4注)
  2. 玩家实况:包括驾驶的船只、所在地点、登录情况等
    • 授权项目例子:esi-location.read_location.v1、esi-location.read_ship_type.v1、esi-corporations.track_members.v1
    • 无法读取的有:开火记录、货柜内容、拾取记录
  3. 建筑:包括建筑地点、燃料耗尽时间、增强情况、增强时间、服务类型与上线情况、解锚时间(精确到秒)等
    • 授权项目例子:esi-corporations.read_structures.v1(需要军团对应权限)
    • 无法读取的有:燃料剩余数目、装备情况、建筑内人数、移动式仓库
  4. 私人机密:包括邮件(收、发、具体内容)、个人位标、资产、克隆、合同、联系人、种菜地址、工业制造情况等
    • 授权项目例子:esi-bookmarks.read_character_bookmarks.v1、esi-assets.read_assets.v1
    • 无法读取的有:聊天框、笔记本
  5. 舰队:包括舰队拉人、踢人、增减中队、设置舰队广告、舰队人员移动
    • 授权项目例子:esi-fleets.write_fleet.v1、esi-fleets.read_fleet
    • 无法实现的有:创建舰队、解散舰队(当然,踢走所有人也不是不可以)

最多一次同时申请四个权限,使用空格连接并URL编码填到上面的scope中,更多的权限可以访问官方ESI查看右上角Authorize中的,Swagger中也给接口标注了需要的权限。

EVE ESI 退出/解绑

当用户不想继续使用ESI,被ESI获取数据,就需要解绑。

  • 中立做法

refresh_token理论上,约1个月不使用,会被服务器清理。

  • 用户做法

EVE官网右上角“ESI解除授权”。

  • 其他做法

据说可以通过OAuth的revoke,或者访问https://login.evepc.163.com/account/logoffhttps://login.evepc.163.com/account/logoff?returnUrl=https%3A%2F%2Flogin.evepc.163.com%2Faccount%2Flogoff来解绑,看起来比较麻烦。

文章参考

参考了部分【虫洞深度自然神秘探索者】中的文章,原文地址


EVE Online 国服 ESI 登录方法记录
https://sodacooky.netlify.app/2023/EVE_ESI/
作者
Sodacooky
发布于
2023年3月26日
许可协议