# API 安全校验加固

**日期**: 2026-03-22
**影响范围**: 全部 16 个微服务
**类型**: 安全加固（纯后端，不影响正常业务流程）

---

## 对前端的影响

### 核心结论：正常使用不受影响

本次改动只增加了输入校验，**不改变任何接口路径、参数名、响应格式**。只要前端传入的数据在合理范围内（正常业务操作都是），完全不受影响。

### 可能触发 400 错误的场景（之前不会报错，现在会）

以下情况会返回 `400 Bad Request`，附带具体的校验错误信息：

#### 1. 字符串超长
所有 DTO 的字符串字段现在有长度限制：
- 名称类字段：最长 50-100 字符
- 描述/备注：最长 500-2000 字符
- 富文本内容：最长 10000-100000 字符
- URL 字段：最长 500-1000 字符

**前端建议**：如果有 `<textarea>` 或富文本编辑器，建议前端也加上 `maxlength` 限制，避免用户输入超长内容后提交失败。

#### 2. 数值范围
- 所有金额字段：不允许负数（`@DecimalMin("0")`）
- 分页 `pageSize`：最大 100（超过自动截断为 100）
- 评分 `rating`：必须 1-5
- 人数字段：`adultCount >= 1`，`childCount >= 0`

#### 3. 列表数量限制
- 出行人 `travelers`：最多 50 人
- 图片列表 `images`：最多 9-20 张
- 视频列表 `videos`：最多 3 个
- 标签列表 `tags`：最多 20-50 个

#### 4. 枚举字段格式
以下字段现在必须严格匹配指定值：
- `refundType`：只能是 `FULL` 或 `PARTIAL`
- `action`（退款审核）：只能是 `APPROVE` 或 `REJECT`
- `sortDir`：只能是 `asc` 或 `desc`

#### 5. 小程序端 DTO 校验
所有小程序 API（`/mp/**`）现在启用了 `@Valid` 校验：
- `phone`：必须匹配 `^1\d{10}$`（11位手机号）
- `code`（登录码）：不能为空
- `content`（评价/反馈）：不能为空，最长 2000-5000 字

---

## 不影响前端的后端内部加固

以下改动完全在后端内部，前端无感知：

| 加固项 | 说明 |
|--------|------|
| 退款并发锁 | Redis 分布式锁防止重复退款 |
| 法大大回调签名验证 | HMAC-SHA256 签名校验 |
| 资源状态修改角色校验 | 仅 SUPER_ADMIN 可直接改状态 |
| 定时任务 Bean 白名单 | 防止执行非授权代码 |
| 文件预览 XSS 防护 | OSS 域名白名单 + HTML 转义 |
| 限流器 IP 防伪造 | 优先使用 X-Real-IP |
| 2FA 端点限流 | 5次/分钟/IP |
| 退款/支付角色校验 | 需要 ADMIN/SUPER_ADMIN/FINANCE 角色 |
| 折扣上限 | 折扣不能等于总价（防 100% 免单） |
| 支付幂等 | Redis 防重复提交 |
| 公式引擎沙箱 | 关键词黑名单 + 循环上限 |

---

## 400 错误响应格式

校验失败时返回格式不变：
```json
{
  "code": 400,
  "message": "参数校验失败",
  "data": {
    "fieldName": "具体的错误提示（中文）"
  }
}
```

**前端建议**：如果尚未统一处理 400 错误，建议在请求拦截器中对 400 状态码做 toast 提示，展示 `data` 中的第一条错误信息。
