diff --git a/hoyolab/user/info.md b/hoyolab/user/info.md index 8ac1509..9a73b5f 100644 --- a/hoyolab/user/info.md +++ b/hoyolab/user/info.md @@ -20,7 +20,7 @@ _请求方式:GET_ | 字段 | 类型 | 内容 | 备注 | | ---- | ---- | ---- | ---- | | uid | num | 米游社账号ID | | -| gids | num | 论坛分区ID | 可选,决定`data`对象→ | +| gids | num | 论坛分区ID | 可选,决定`data`对象→`user_info`对象→`level_exp`对象的内容 | **JSON返回:** @@ -38,7 +38,7 @@ _请求方式:GET_ | ---- | ---- | ---- | ---- | | user_info | obj | 该用户的详细信息 | | | follow_relation | obj | 请求Cookie对应用户与该用户的关系 | | -| auth_relations | obj | 待调查 | 似乎总是都为空对象 | +| auth_relations | obj | 待调查 | 似乎总为空对象 | | is_in_blacklist | bool | 是否被封禁 | | | is_has_collection | bool | 是否拥有文章合集 | | | is_creator | bool | false | | @@ -348,9 +348,11 @@ _请求方式:GET_ _请求方式:POST_ -> _需要验证应用Cookie_ +> _需要验证SToken_ +`https://api-takumi.miyoushe.com/binding/api/genAuthKey` `https://api-takumi.miyoushe.com/account/auth/api/genAuthKey` +`https://hk4e-sdk.mihoyo.com/hk4e_cn/combo/granter/login/genAuthKey` **JSON请求:** diff --git a/other/authentication.md b/other/authentication.md index 868a68d..7ebef38 100644 --- a/other/authentication.md +++ b/other/authentication.md @@ -7,7 +7,7 @@ 大多数API需要验证请求头。 -部分API(例如点赞文章、《原神》米游社签到、米游币等)需要使用Cookie鉴权。 +部分API(例如点赞文章、米游社签到福利、米游币等)需要使用Cookie鉴权。 ## 请求头 @@ -15,61 +15,53 @@ 大多数API需要验证的请求头:`x-rpc-app_version`、`x-rpc-client_type`、`x-rpc-device_id`、`X-Requested-With`、`Origin`、`Referer`、`Host`、`DS`、`User-Agent`。 -少数API才需要验证的额外的请求头:`x-rpc-page`、`x-rpc-challenge`。 +少数API才需要验证的额外的请求头:`x-rpc-device_fp`、`x-rpc-challenge`。 -可选请求头:`x-rpc-device_fp`、`x-rpc-device_name`、`x-rpc-device_model`、`x-rpc-sys_version`、`x-rpc-channel`。 +可选请求头:`x-rpc-device_name`、`x-rpc-device_model`、`x-rpc-sys_version`、`x-rpc-channel`。 #### `x-rpc-app_version` -米游社版本号,例如`2.44.1`。 +米游社版本号,例如`2.50.1`。 -与DS字段相关,DS生成需要`salt`,而每个米游社版本的`salt`都不同。 +与`DS`字段相关,`DS`生成需要`salt`,而每个米游社版本的`salt`都不同。 -因此1个米游社版本只能使用对应的1个`salt`用于生成DS。 +因此米游社版本只能使用对应的`salt`用于生成DS。 #### `x-rpc-client_type` -APP为`2`或`5`,网页为`4`。 +有`2`、`4`和`5`这些值。 根据请求的API不同而变化。 将会在需要验证请求头的API进行标注。 -与DS字段相关,DS生成需要`salt`,而不同的`x-rpc-client_type`对应该版本米游社的`salt`也不同。 +与`DS`字段相关,`DS`生成需要`salt`,而不同的`x-rpc-client_type`对应该版本米游社的`salt`也不同。 -#### `x-rpc-sys_version`(可选) +#### `x-rpc-sys_version` 安卓系统大版本版本号,例如Android 13则为`13`。 -#### `x-rpc-channel`(可选) +#### `x-rpc-channel` 手机厂商,例如小米则为`xiaomi`。 -#### `x-rpc-device_name`(可选) +#### `x-rpc-device_name` 手机厂商和手机型号,例如小米11青春版则为`Xiaomi M2101K9C`。 -#### `x-rpc-device_model`(可选) +#### `x-rpc-device_model` 手机型号。 -#### `x-rpc-device_fp`(可选) +#### `x-rpc-device_fp` -向`https://public-data-api.mihoyo.com/device-fp/api/getFp`发送一些设备信息以获得。 +发送POST请求至`https://public-data-api.mihoyo.com/device-fp/api/getFp`以获得。 #### `x-rpc-device_id` -未知其规律,可以从请求中复制。 - -#### `x-rpc-page` - -少数API需要验证,未知其规律。 - -`3.1.3_#/ys` - -`/ys` +设备ID,由使用的设备决定。 #### `X-Requested-With` @@ -105,21 +97,21 @@ APP为`2`或`5`,网页为`4`。 #### `User-Agent` -无需验证请求头或`x-rpc-client_type`为`2`的API不需要设置请求头。 +大多数`x-rpc-client_type`为`2`和`4`的API不需要设置该请求头。 -但尽量避免带有`python`等字样。 +但尽量避免带有`python`、`curl`等字样。 -需要验证请求头的API的用户代理为`Mozilla/5.0 (Linux; Android 安卓大版本号; 手机型号 Build/TKQ1.220829.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 miHoYoBBS/米游社版本号`。 +需要验证请求头的API的用户代理格式为`Mozilla/5.0 (Linux; Android 安卓系统大版本号; 手机型号 Build/TKQ1.220829.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 miHoYoBBS/米游社版本号`。 -例如`Mozilla/5.0 (Linux; Android 13; M2101K9C Build/TKQ1.220829.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 miHoYoBBS/2.44.1` +例如`Mozilla/5.0 (Linux; Android 13; M2101K9C Build/TKQ1.220829.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 miHoYoBBS/2.51.1` #### `DS` -_DS(Dynamic Secret,动态密钥)_ +动态签名(Dynamic Sign),别称“数据签名(Data Sign)”“动态密钥(Dynamic Secret)” 大多数API需要验证请求头中的`DS`字段。 -DS值通过一系列算法得出。 +`DS`值通过一系列算法得出。 ##### 生成`DS` @@ -127,7 +119,6 @@ DS值通过一系列算法得出。 * 网页、中国版APP和国际版APP的生成算法不同。 * 请求头的`x-rpc-client_type`字段,每个值都有其对应的生成算法。 -* 少数API有其单独的生成算法。 生成`DS`需要`salt`(为32个包含大写字母、小写字母、数字的字符串)。 @@ -136,20 +127,24 @@ DS值通过一系列算法得出。 * 网页、中国版APP和国际版APP使用的`salt`不同。 * 每个APP版本都存有其独有的`salt`。 * 请求头的`x-rpc-client_type`字段,每个值使用的`salt`不同。 -* 少数API有其单独的`salt`(例如米游社社区签到)。 +* 少数API有其单独的`salt`(例如米游社签到福利)。 -请在[这里](https://github.com/Kamisato-Ayaka-233/mihoyo-api-collect/issues/1#issue-1571906738)获取`salt`。 +请在[这里](https://github.com/Kamisato-Ayaka-233/mihoyo-api-collect/issues/1)获取`salt`。 ###### 中国版APP: -**当`x-rpc-client_type`为`5`时**: +`DS`有多个生成算法,分别为`DS1`和`DS2`。 + +**`DS2`**: + +在请求头中的`x-rpc-client_type`为`5`时使用。 整体思路: 1. 获取当前的Unix时间戳(整数)。 1. 在100000到200000中选取随机整数,但是如果随机到100000,则加上542367,得到642367。 -1. 若将发送Post请求,则将发送的数据转为JSON字符串,存储至变量(下文称`body`)。若将发送Get请求,则将URL参数进行英文字母顺序排序(键)后存储至变量(下文称`query`),例如URL参数为`server=cn_gf01&role_id=114514191`则结果为`role_id=222681079&server=cn_gf01`。若不需要传递数据或URL参数,则为空字符串。 +1. 若将发送POST请求,则将发送的数据转为JSON字符串并使用对象的键进行英文字母顺序排序,存储至变量(下文称`body`)。若将发送GET请求,则将URL参数进行英文字母顺序排序(键)后存储至变量(下文称`query`),例如URL参数为`server=cn_gf01&role_id=114514191`则结果为`role_id=222681079&server=cn_gf01`。若不需要传递数据或URL参数,则为空字符串。 1. 格式化字符串:`salt={salt值}&t={第1步的结果}&r={第2步的结果}&b={第3步的body}&q={第3步的query}`。 1. 将第4步的结果进行UTF-8编码,再进行MD5编码。 1. 格式化字符串:`{第1步的结果},{第2步的结果},{第5步的结果}`。 @@ -159,11 +154,14 @@ Python: import time import random from hashlib import md5 +# JSON模块用于处理POST请求的JSON数据 +# import json -# 将要使用的salt,此为2.44.1版本的salt。 +# 将要使用的salt,此为4X salt salt = "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs" -# body和query一般来说不会同时存在。 -# 可以使用json库的dumps函数将对象转为JSON字符串。 +# body和query一般来说不会同时存在。毕竟body只有POST请求才有,query只有GET请求才有 +# 可以使用json库的dumps函数将对象转为JSON字符串 +# body = json.dumps({"role": "123456789"}, sort_keys=True) body = '{"role": "123456789"}' # 可以使用urllib中的parse库的urlparse函数,传入URL,得到返回值中的query字段。 # 将其转为列表(通过str.split("&")),通过sorted函数来排序,再用"&".join来将其转为最终值 @@ -178,10 +176,34 @@ if r == 100000: main = f"salt={salt}&t={t}&r={r}&b={body}&q={query}" ds = md5(main.encode(encoding='UTF-8')).hexdigest() -final = f"{t},{r},{ds}" # 最终结果。 +final = f"{t},{r},{ds}" # 最终结果 ``` -**当`x-rpc-client_type`为`2`时**: +JavaScript: +```js +import md5 from 'md5' + +const salt = "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs" + +const body = '{"role": "123456789"}' +const query = "server=cn_gf01&role_id=123456789" + +const t = Math.floor(Date.now() / 1000) +let r = Math.floor(Math.random() * 100001 + 100000) +if (r == 100000) { + r = 642367 +} +// const r = Math.floor(Math.random() * 100001 + 100001) + +const main = f"salt={salt}&t={t}&r={r}&b={body}&q={query}" +const ds = md5(main) + +const final = `${t},${r},${ds}` // 最终结果 +``` + +**`DS1`**: + +在请求头中的`x-rpc-client_type`为`5`时使用。 整体思路: @@ -200,7 +222,7 @@ from hashlib import md5 lettersAndNumbers = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' -# 将要使用的salt,此为2.35.2版本的salt。 +# 将要使用的salt,此为2.35.2版本的K2 salt。 salt = "ZSHlXeQUBis52qD1kEgKt5lUYed4b7Bb" t = int(time.time()) @@ -211,13 +233,28 @@ ds = md5(main.encode(encoding='UTF-8')).hexdigest() final = f"{t},{r},{ds}" # 最终结果。 ``` -**当`x-rpc-client_type`为`4`(网页)时**: +JavaScript: +```js +import md5 from 'md5' -未知 +const salt = "ZSHlXeQUBis52qD1kEgKt5lUYed4b7Bb" +const lettersAndNumbers = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + +const t = Math.floor(Date.now() / 1000) +let r = "" +for (let i;i < 6;i++) { + r += lettersAndNumbers[Math.floor(Math.random() * lettersAndNumbers.length)] +} + +const main = f"salt={salt}&t={t}&r={r}" +const ds = md5(main) + +const final = `${t},${r},${ds}` // 最终结果 +``` ## Cookie -一些API(例如文章点赞、签到等)需要登录账号,则表示为Cookie的形式。 +一些API(例如文章点赞、签到和获取用户的游戏账号信息等API)需要登录账号,则表示为请求头Cookie的形式。 需要验证Cookie的API会进行标注。 @@ -225,35 +262,44 @@ final = f"{t},{r},{ds}" # 最终结果。 ### 米游社 -网页(`x-rpc-client_type`为`5`或`4`)、应用端(`x-rpc-client_type`为`2`)的Cookie形式不同。 +需要哪些Cookie取决于以下因素: -注意:“网页Cookie”和“应用Cookie”只是随意取的名称,不意味着网页Cookie只用在网页端,同样,也不意味着应用Cookie只用在应用端。只是为了分组而已。 +* API是否要求登录账号。 +* `x-rpc-client_type`的不同值。 +* 一些API要求特殊的Cookie。 -**网页:** +#### LToken -若API需要验证网页Cookie,以下字段必须存在,否则返回`10001`: +即`ltoken_v2`和`ltoken`。 -* `ltoken_v2` -* `ltmid_v2` +`ltoken_v2`多用于查询用户的游戏账号信息。 -以下字段可选: +必须与[`ltmid_v2`](#mihoyo-id)一起使用。 -* `cookie_token_v2` - 例如米游社签到福利(游戏内道具)需要验证该字段,一段时间内刷新 -* `account_mid_v2` - 与`ltmid_v2`相同 -* `account_id_v2` - 米游社UID -* `ltuid_v2` - 米游社UID -* `login_ticket` - 米游社的登录凭证 - +#### SToken -**应用:** +即`stoken`。 -若API需要验证应用Cookie,以下字段必须存在: +`stoken`多用于在米游社内的操作。 -* `stoken` -* `mid` +必须与[`mid`](#mihoyo-id)一起使用。 + +#### Mihoyo ID + +分为与[LToken](#ltoken)一起使用的`ltmid_v2`,和与[SToken](#stoken)一起使用的`mid` + +`ltmid_v2`和`mid`的值是相同,对应一个账号。 + +#### Login Ticket + +即`login_ticket`。 + +`login_ticket`是米游社的登录凭证,隔一段时间刷新。作用未知。 + +#### Cookie Token + +即`cookie_token_v2`。 + +`cookie_token_v2`隔一段时间刷新。作用未知。 -以下字段可选: -* `stuid` - 米游社UID