修改描述

增加`DS`生成方法的JS代码
将`x-rpc-device_fp`请求头归类至“少数API需要验证的请求头”
This commit is contained in:
Kamisato-Ayaka-233 2023-06-03 12:30:20 +08:00
parent c999e752c1
commit 7816443129
2 changed files with 115 additions and 67 deletions

View File

@ -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请求**

View File

@ -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`
_DSDynamic 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` - 米游社的登录凭证
<!-- * `_MHYUUID`
* `DEVICEFP`
* `acw_tc` -->
#### 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