# 错误与频控

按 HTTP 状态码处理认证、授权、发布、频控和服务异常。

## 错误响应

```json
{
  "code": 403,
  "message": "应用无权访问该接口",
  "data": []
}
```

外部响应只保证 `code`、`message` 和 `data`。内部审计错误码不会作为 JSON 字段返回，客户端不要假设存在 `error_code`。

## HTTP 状态码

| 状态  | 常见场景                                                | 建议处理                                     |
| ----- | ------------------------------------------------------- | -------------------------------------------- |
| `401` | 缺少、无效或过期的 Access Token；应用禁用；应用凭证错误 | 尝试刷新一次令牌；失败后停止请求并联系管理员 |
| `403` | 应用未获得该接口授权                                    | 不重试，请管理员检查接口授权                 |
| `404` | 路由不存在或未使用 OpenAPI 机制发布                     | 检查路径和接口发布状态                       |
| `405` | 路径存在但 HTTP 方法错误                                | 使用 `Allow` 响应头中的方法                  |
| `422` | JSON 请求字段缺失、类型或长度不合法                     | 修正请求参数后重试                           |
| `429` | 认证频控、连续认证失败冻结、QPS 或 30 天额度用尽        | 按 `Retry-After` 延迟重试                    |
| `500` | 未识别的内部异常                                        | 记录 `X-Request-Id`，进行有限次数退避重试    |
| `503` | Redis 频控不可用或接口频控配置缺失                      | 记录请求 ID，退避重试并通知平台管理员        |

`401` 响应包含 `WWW-Authenticate: Bearer`。所有 OpenAPI 响应都包含 `X-Request-Id`，可用于关联平台调用日志。

## 业务接口频控

频控按 `应用 ID + 接口 ID` 独立计数，不同应用和接口互不影响。

- QPS 使用 1 秒固定窗口。
- 30 天额度从当前计数周期第一次调用开始，周期为固定 2,592,000 秒，不按自然月重置。
- 默认新接口启用频控，QPS 为 `10`，30 天总量为 `100000`；管理员可以修改或关闭。
- 频控启用时 Redis 不可用会返回 `503`，不会无限放行。

成功响应可能包含：

| 响应头                      | 说明                       |
| --------------------------- | -------------------------- |
| `X-RateLimit-Status`        | `enabled` 或 `disabled`    |
| `X-RateLimit-QPS-Limit`     | 每秒上限                   |
| `X-RateLimit-QPS-Remaining` | 当前秒窗口剩余量           |
| `X-RateLimit-30d-Limit`     | 当前 30 天周期总量         |
| `X-RateLimit-30d-Remaining` | 当前周期剩余量             |
| `X-RateLimit-30d-Reset`     | 当前周期重置的 Unix 时间戳 |

频控拒绝还会返回 `Retry-After`，单位为秒。

## 认证接口默认限制

下表是插件默认配置，部署环境可以覆盖：

| 接口或维度                   | 默认限制     |
| ---------------------------- | ------------ |
| 获取令牌，来源 IP            | 每分钟 10 次 |
| 获取令牌，App Key 与来源 IP  | 每分钟 5 次  |
| 刷新令牌，来源 IP            | 每分钟 30 次 |
| 刷新令牌，Refresh Token 指纹 | 每分钟 10 次 |
| 吊销令牌，来源 IP            | 每分钟 30 次 |

同一凭证连续获取令牌失败达到 5 次后，会从 60 秒开始指数冻结，最长 15 分钟。认证成功会清理对应失败状态。

## 重试建议

- `401`：只允许一次刷新并重放；刷新失败后要求重新配置凭证。
- `403`、`404`、`405`、`422`：修正配置或请求，不做自动重试。
- `429`：严格等待 `Retry-After`，并增加少量随机抖动。
- `500`、`503`：使用有上限的指数退避，并保留 `X-Request-Id`。
- 非幂等业务请求在没有业务幂等键时不要自动重放。

## 日志安全

调用方日志建议记录方法、路径、HTTP 状态、业务 `code`、耗时和 `X-Request-Id`。不要记录：

- App Secret
- 完整 Access Token 或 Refresh Token
- `Authorization`、Cookie
- 含敏感数据的完整请求体和响应体
