优化,添加115接口文档

This commit is contained in:
truewhile
2026-09-05 14:32:58 +08:00
parent d00b14df55
commit 0e9fb2c937
57 changed files with 5682 additions and 76 deletions
@@ -0,0 +1,92 @@
## 刷新access_token
### 基本信息
| 属性 | 内容 |
|:-----------|:---------------------------------|
| 接口名称 | 刷新access_token |
| 接口版本 | v1.0 |
| 接口路径 | /refreshToken |
| 请求方法 | POST |
| 接口状态 | 生产环境 |
### 接口说明
该接口用于通过 `refresh_token` 获取新的 `access_token` 和 `refresh_token`。
### 接口地址
```
https://passportapi.115.com/open/refreshToken
```
### 请求方式
```
POST
Content-Type: application/x-www-form-urlencoded
```
### 认证方式
```
OAuth 2.0 刷新凭证
```
### 请求参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 | 约束/示例 |
|:-------------|:-------|:---|:----|:---------------------|:----------------------------|
| refresh_token | string | 是 | - | 用于刷新访问凭证的刷新凭证 | `REFRESH_TOKEN_PLACEHOLDER` |
### 请求示例
```shell
curl 'https://passportapi.115.com/open/refreshToken' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'refresh_token=REFRESH_TOKEN_PLACEHOLDER'
```
### 响应字段说明
| 字段 | 类型 | 描述 |
|:-------------------|:-------|:------------------------------------|
| state | int | 状态码 |
| code | int | 错误码 |
| message | string | 响应信息 |
| data | object | 响应数据 |
| data.access_token | string | 新的 `access_token`,同时刷新有效期 |
| data.refresh_token | string | 新的 `refresh_token`,其有效期不延长、不改变 |
| data.expires_in | int | `access_token` 有效期,单位为秒 |
### 响应示例
```json
{
"state": 1,
"code": 0,
"message": "",
"data": {
"access_token": "ACCESS_TOKEN_PLACEHOLDER",
"refresh_token": "REFRESH_TOKEN_PLACEHOLDER",
"expires_in": 7200
}
}
```
### 注意事项
- `access_token` 有效期为 7200 秒,调用方应以响应中的 `expires_in` 计算刷新时间。
- 同一授权在 60 秒内重复刷新会触发频率控制;多进程或多节点调用方应确保同一授权同一时间只有一个刷新请求。
- 调用后会同时生成新的 `access_token` 和 `refresh_token`。调用方必须将两者作为一组原子保存,并停止使用刷新前的旧凭证;刷新凭证本身的有效期不延长、不改变。
- 收到 `40140125` 或 `40140126` 时,不要使用原 `access_token` 重复重试。应先读取已保存的最新凭证;没有可用新凭证时,再调用本接口刷新。
- `40140116`、`40140119`、`40140120` 是终态错误,用同一个 `refresh_token` 重试永远不会成功。同一 `refresh_token` 连续多次以这三种原因失败会被服务端标记为永久失效,之后每次刷新都直接返回 `40140137`。客户端收到这三种错误或 `40140137` 时必须停止重试,引导用户重新授权;后台常驻程序(如 NAS 同步任务)尤其要实现该逻辑,避免长期无效轮询。
- `access_token` 和 `refresh_token` 属于敏感凭证,不得写入公开仓库、客户端日志或公开沟通内容。
### 修改历史
| 修改时间 | 修改说明 |
|:-----------------------------|:-----|
| 2025年04月01日(周二) 00:00:00 | 创建文档 |
| 2026年08月10日(周一) 10:23:15 | 修正 `access_token` 有效期示例,补充凭证轮换及并发刷新说明 |
| 2026年08月24日(周一) 10:16:52 | 新增 `refresh_token` 永久失效判定规则与终态错误码 `40140137` 说明 |
@@ -0,0 +1,88 @@
## 获取access_token
### 基本信息
| 属性 | 内容 |
|:-----------|:---------------------------------|
| 接口名称 | 获取access_token |
| 接口版本 | v1.0 |
| 接口路径 | /deviceCodeToToken |
| 请求方法 | POST |
| 接口状态 | 生产环境 |
### 接口说明
该接口用于在用户确认手机扫码授权后,使用设备码和 PKCE 原始校验值换取 `access_token`。
### 接口地址
```
https://passportapi.115.com/open/deviceCodeToToken
```
### 请求方式
```
POST
Content-Type: application/x-www-form-urlencoded
```
### 认证方式
```
OAuth 2.0 + PKCE
```
### 请求参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 | 约束/示例 |
|:-----------|:-------|:---|:----|:--------------------------------|:---------------------------------------------------------------|
| uid | string | 是 | - | 二维码 ID/设备码 | `DEVICE_CODE_PLACEHOLDER` |
| code_verifier | string | 是 | - | 计算 `code_challenge` 时使用的原始随机字符串 | `IGKN6CJanWxCDPDhHZJrhswQdlcPBGLqExkhyujysXaQ4fJKBk_6dlPJo47s` |
### 请求示例
```shell
curl 'https://passportapi.115.com/open/deviceCodeToToken' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'uid=DEVICE_CODE_PLACEHOLDER' \
--data-urlencode 'code_verifier=IGKN6CJanWxCDPDhHZJrhswQdlcPBGLqExkhyujysXaQ4fJKBk_6dlPJo47s'
```
### 响应字段说明
| 字段 | 类型 | 描述 |
|:-------------------|:-------|:--------------------------------|
| state | int | 状态码 |
| code | int | 错误码 |
| message | string | 响应信息 |
| data | object | 响应数据 |
| data.access_token | string | 访问资源接口的凭证 |
| data.refresh_token | string | 刷新 `access_token` 的凭证,有效期 1 年 |
| data.expires_in | int | `access_token` 有效期,单位为秒 |
### 响应示例
```json
{
"state": 1,
"code": 0,
"message": "",
"data": {
"access_token": "ACCESS_TOKEN_PLACEHOLDER",
"refresh_token": "REFRESH_TOKEN_PLACEHOLDER",
"expires_in": 7200
}
}
```
### 注意事项
- `code_verifier` 必须与生成 `code_challenge` 时使用的原始值一致。
- `access_token` 和 `refresh_token` 属于敏感凭证,不得写入公开仓库、客户端日志或公开沟通内容。
### 修改历史
| 修改时间 | 修改说明 |
|:-----------------------------|:-----|
| 2025年04月01日(周二) 00:00:00 | 创建文档 |
@@ -0,0 +1,103 @@
## 获取设备码和二维码内容
### 基本信息
| 属性 | 内容 |
|:-----------|:---------------------------------|
| 接口名称 | 获取设备码和二维码内容 |
| 接口版本 | v1.0 |
| 接口路径 | /authDeviceCode |
| 请求方法 | POST |
| 接口状态 | 生产环境 |
### 接口说明
该接口用于 OAuth 2.0 + PKCE 手机扫码授权流程的第一步,获取设备码和二维码内容。此模式适用于无后端服务的第三方客户端,无需提供 AppSecret。
第三方客户端需要根据响应中的 `data.qrcode` 生成二维码,供 115 客户端扫码授权。
### 接口地址
```
https://passportapi.115.com/open/authDeviceCode
```
### 请求方式
```
POST
Content-Type: application/x-www-form-urlencoded
```
### 认证方式
```
OAuth 2.0 + PKCE
```
### 请求参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 | 约束/示例 |
|:---------------------|:-------|:---|:----|:--------------------------------|:-----------------------------------------------------------|
| client_id | string | 是 | - | AppID | `YOUR_APP_ID` |
| code_challenge | string | 是 | - | PKCE 挑战码 | `THHodGWg-FZfv8XYz7QArNGIK_aVomSHPldlSOTUtkw` |
| code_challenge_method | string | 是 | - | `code_challenge` 的哈希算法,见下方枚举表格 | `sha256` |
#### 请求参数中的 code_challenge_method 字段枚举
| 值 | 说明 | 备注 |
|:-------|:---------------------------|:---|
| md5 | 使用 MD5 计算挑战码 | - |
| sha1 | 使用 SHA-1 计算挑战码 | - |
| sha256 | 使用 SHA-256 计算挑战码,推荐使用 | - |
### 请求示例
```shell
curl 'https://passportapi.115.com/open/authDeviceCode' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=YOUR_APP_ID' \
--data-urlencode 'code_challenge=THHodGWg-FZfv8XYz7QArNGIK_aVomSHPldlSOTUtkw' \
--data-urlencode 'code_challenge_method=sha256'
```
### 响应字段说明
| 字段 | 类型 | 描述 |
|:-----------|:-----|:------------------------------------------|
| state | int | 状态码 |
| code | int | 错误码 |
| message | string | 响应信息 |
| data | object | 响应数据 |
| data.uid | string | 设备码,轮询二维码状态时使用 |
| data.time | int | 校验时间戳,轮询二维码状态时使用 |
| data.qrcode | string | 二维码内容,第三方客户端需要据此生成设备二维码 |
| data.sign | string | 校验签名,轮询二维码状态时使用 |
### 响应示例
```json
{
"state": 1,
"code": 0,
"message": "",
"data": {
"uid": "DEVICE_CODE_PLACEHOLDER",
"time": 0,
"qrcode": "QRCODE_CONTENT_PLACEHOLDER",
"sign": "SIGN_PLACEHOLDER"
}
}
```
### 注意事项
- `code_verifier` 为长度 43 至 128 位的随机字符串。
- `code_challenge` 的计算方式为 `url_safe(base64_encode(hash(code_verifier)))`。哈希结果按二进制数据参与 Base64 编码,算法需要与 `code_challenge_method` 一致。
- AppID 等应用凭证请使用实际应用配置,不要在公开仓库或日志中记录敏感凭证。
### 修改历史
| 修改时间 | 修改说明 |
|:-----------------------------|:-----|
| 2025年04月01日(周二) 00:00:00 | 创建文档 |
@@ -0,0 +1,89 @@
## 轮询二维码状态
### 基本信息
| 属性 | 内容 |
|:-----------|:---------------------------------|
| 接口名称 | 轮询二维码状态 |
| 接口版本 | v1.0 |
| 接口路径 | /get/status/ |
| 请求方法 | GET |
| 接口状态 | 生产环境 |
### 接口说明
该接口用于长轮询设备二维码的扫码和授权状态。当二维码状态没有变化时,接口不会立即响应,直到请求超时或状态发生变化。
### 接口地址
```
https://qrcodeapi.115.com/get/status/
```
### 请求方式
```
GET
```
### 认证方式
```
设备码参数校验
```
### 请求参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 | 约束/示例 |
|:----|:-------|:---|:----|:------------------------------------|:------------------------|
| uid | string | 是 | - | 二维码 ID/设备码,从 `/open/authDeviceCode` 的 `data.uid` 获取 | `DEVICE_CODE_PLACEHOLDER` |
| time | int | 是 | - | 校验时间戳,从 `/open/authDeviceCode` 的 `data.time` 获取 | `0` |
| sign | string | 是 | - | 校验签名,从 `/open/authDeviceCode` 的 `data.sign` 获取 | `SIGN_PLACEHOLDER` |
### 请求示例
```shell
curl -G 'https://qrcodeapi.115.com/get/status/' \
--data-urlencode 'uid=DEVICE_CODE_PLACEHOLDER' \
--data-urlencode 'time=0' \
--data-urlencode 'sign=SIGN_PLACEHOLDER'
```
### 响应字段说明
| 字段 | 类型 | 描述 |
|:------------|:-------|:-------------------------------------------|
| state | int | 轮询状态:0-二维码无效,结束轮询;1-继续轮询 |
| code | int | 错误码 |
| message | string | 响应信息 |
| data | object | 响应数据;115 客户端扫码或输入设备码后才有值 |
| data.msg | string | 操作提示 |
| data.status | int | 二维码状态:1-扫码成功,等待确认;2-确认登录或授权,结束轮询 |
| data.version | string | 版本信息 |
### 响应示例
```json
{
"state": 1,
"code": 0,
"message": "",
"data": {
"msg": "OPERATION_MESSAGE_PLACEHOLDER",
"status": 1,
"version": "VERSION_PLACEHOLDER"
}
}
```
### 注意事项
- `state=0` 表示二维码无效,应结束轮询;`state=1` 表示继续轮询。
- `data.status=1` 表示扫码成功并等待用户确认;`data.status=2` 表示用户已确认登录或授权,应结束轮询并进入换取访问凭证的步骤。
- 长轮询超时不等同于授权失败,客户端可以按照自身网络策略重新发起请求。
### 修改历史
| 修改时间 | 修改说明 |
|:-----------------------------|:-----|
| 2025年04月01日(周二) 00:00:00 | 创建文档 |
@@ -0,0 +1,95 @@
## 用授权码换取access_token
### 基本信息
| 属性 | 内容 |
|:-----------|:---------------------------------|
| 接口名称 | 用授权码换取access_token |
| 接口版本 | v1.0 |
| 接口路径 | /authCodeToToken |
| 请求方法 | POST |
| 接口状态 | 生产环境 |
### 接口说明
该接口用于通过授权码换取 `access_token`。建议在开发者服务端调用,避免泄露 AppSecret。
### 接口地址
```
https://passportapi.115.com/open/authCodeToToken
```
### 请求方式
```
POST
Content-Type: application/x-www-form-urlencoded
```
### 认证方式
```
OAuth 2.0 授权码模式
```
### 请求参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 | 约束/示例 |
|:-------------|:-------|:---|:----|:------------------------------------|:------------------------------|
| client_id | string | 是 | - | AppID | `YOUR_APP_ID` |
| client_secret | string | 是 | - | AppSecret | `YOUR_APP_SECRET` |
| code | string | 是 | - | 请求授权接口重定向返回的授权码 | `AUTHORIZATION_CODE_PLACEHOLDER` |
| redirect_uri | string | 是 | - | 与请求授权时传入的 `redirect_uri` 一致,用于防止 MITM 和 CSRF 攻击 | `https://foo.com?state=123456` |
| grant_type | string | 是 | - | 授权类型,固定为 `authorization_code` | `authorization_code` |
### 请求示例
```shell
curl 'https://passportapi.115.com/open/authCodeToToken' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=YOUR_APP_ID' \
--data-urlencode 'client_secret=YOUR_APP_SECRET' \
--data-urlencode 'code=AUTHORIZATION_CODE_PLACEHOLDER' \
--data-urlencode 'redirect_uri=https://foo.com?state=123456' \
--data-urlencode 'grant_type=authorization_code'
```
### 响应字段说明
| 字段 | 类型 | 描述 |
|:-------------------|:-------|:--------------------------------|
| state | int | 状态码:0-失败;1-成功 |
| code | int | 错误码 |
| message | string | 响应信息 |
| data | object | 响应数据 |
| data.access_token | string | 访问资源接口的凭证 |
| data.refresh_token | string | 刷新 `access_token` 的凭证,有效期 1 年 |
| data.expires_in | int | `access_token` 有效期,单位为秒 |
### 响应示例
```json
{
"state": 1,
"code": 0,
"message": "",
"data": {
"access_token": "ACCESS_TOKEN_PLACEHOLDER",
"refresh_token": "REFRESH_TOKEN_PLACEHOLDER",
"expires_in": 7200
}
}
```
### 注意事项
- 必须在服务端安全保存并使用 AppSecret,不得在客户端代码、公开仓库或日志中泄露。
- `redirect_uri` 必须与请求授权时传入的值一致。
- `access_token` 和 `refresh_token` 属于敏感凭证,应按照敏感数据规范存储。
### 修改历史
| 修改时间 | 修改说明 |
|:-----------------------------|:-----|
| 2025年04月01日(周二) 00:00:00 | 创建文档 |
@@ -0,0 +1,87 @@
## 请求授权
### 基本信息
| 属性 | 内容 |
|:-----------|:---------------------------------|
| 接口名称 | 请求授权 |
| 接口版本 | v1.0 |
| 接口路径 | /authorize |
| 请求方法 | GET |
| 接口状态 | 生产环境 |
### 接口说明
该接口用于发起 OAuth 2.0 授权码模式授权,建议由开发者服务端参与授权流程。
用户未登录时,接口会重定向到登录页面;用户已登录时,接口会自动完成授权并重定向到 `redirect_uri` 指定的地址。
### 接口地址
```
https://passportapi.115.com/open/authorize
```
### 请求方式
```
GET
```
### 认证方式
```
OAuth 2.0 授权码模式
```
### 请求参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 | 约束/示例 |
|:-----------|:-------|:---|:----|:-----------------------------------------------|:---------------------|
| client_id | string | 是 | - | AppID | `YOUR_APP_ID` |
| redirect_uri | string | 是 | - | 授权完成后的重定向地址;接口会附加授权码 `code`,并原样附加请求中的 `state` | `https://foo.com/bar` |
| response_type | string | 是 | - | 授权模式,固定为 `code` | `code` |
| state | string | 否 | "" | 防止 CSRF 攻击的随机值,重定向时原样返回 | `123456` |
### 请求示例
```shell
curl -G 'https://passportapi.115.com/open/authorize' \
--data-urlencode 'client_id=YOUR_APP_ID' \
--data-urlencode 'redirect_uri=https://foo.com/bar' \
--data-urlencode 'response_type=code' \
--data-urlencode 'state=123456'
```
### 响应字段说明
接口调用成功时会重定向到 `redirect_uri`,并通过查询参数返回授权码 `code` 和请求中携带的 `state`。接口调用失败时返回以下字段:
| 字段 | 类型 | 描述 |
|:--------|:-------|:------------------|
| state | int | 状态码:0-失败;1-成功 |
| code | int | 错误码 |
| data | object | 响应数据 |
| message | string | 响应信息 |
### 响应示例
```json
{
"state": 0,
"code": 40140127,
"data": {},
"message": "response_type 错误"
}
```
### 注意事项
- `redirect_uri` 需要先在[115生活开放平台](https://open.115.com/)的应用管理中配置域名,并在请求时进行 URL 编码。
- 强烈建议传入随机 `state`,并在换取 `access_token` 前验证重定向返回的 `state` 与请求值一致,以防止 CSRF 攻击。
### 修改历史
| 修改时间 | 修改说明 |
|:-----------------------------|:-----|
| 2025年04月01日(周二) 00:00:00 | 创建文档 |