Appearance
安全设计
认证与防重放
| 措施 | 说明 |
|---|---|
| HMAC 签名 | 请求体 + query 参数均参与签名,防篡改 |
| 时间戳校验 | ±5分钟窗口,防重放 |
| Nonce 唯一性 | Redis 存储 10分钟,每次请求必须使用新的随机 nonce |
| IP 白名单 | 可选配置,限定调用来源 IP |
| 接口级权限 | permissions JSON 字段控制可调用哪些接口 |
| 客户端过期 | expires_at 支持临时授权,到期自动失效 |
| 调用审计 | 全量记录调用日志,含耗时、状态码、错误信息 |
| 请求体限制 | 普通接口 1MB,批量/导入 5MB,图片上传 50MB |
密钥管理
生成规则
| 字段 | 生成方式 | 示例 |
|---|---|---|
app_key | {系统标识}_{随机16字符} | crm_a3f8b2c1d4e5f678 |
app_secret | secrets.token_hex(32) | 64 字符十六进制字符串 |
webhook_secret | secrets.token_hex(16) | 32 字符十六进制字符串 |
存储安全
- 生产环境:
app_secret和webhook_secret使用 AES-256-GCM 加密存储 - 加密密钥从环境变量
OPEN_API_ENCRYPT_KEY读取,不写入代码或数据库 - 开发环境可明文存储
密钥轮换
支持不中断服务的密钥轮换:
1. 通过管理脚本执行密钥轮换
2. 系统生成新的 app_secret
3. 当前 app_secret 移入 app_secret_old,新 secret 写入 app_secret
4. 记录 secret_rotated_at 为当前时间
5. 调用方可同时使用新旧两个 secret 签名
(验证时先试当前密钥,失败再试旧密钥)
6. 过渡期(默认 7 天)后,app_secret_old 自动清空首次获取
app_secret 仅在创建客户端时返回一次,后续无法再次查看(只能重置)。
脱敏策略
| 场景 | 策略 |
|---|---|
| 开放接口默认 | 不脱敏(内部系统间传递完整数据) |
| 特定客户端需脱敏 | 通过 sanitize_enabled = 1 启用 |
| 脱敏规则 | 手机号中间四位 → ****、身份证中间十位 → * |
健康检查安全
GET /api/open/v1/health 需要签名认证(与其他接口一致),避免暴露服务状态给未授权方。