Appearance
限流与安全规范
本章导读:限流不是运维的 nginx 配置就完事——做得好,它是一份"客户端可编程的契约"(何时重试、还剩多少配额,全部写进标准头部)。安全篇则按 OWASP API Security Top 10 的视角,给出 REST 特有的风险清单与防护规范。
1. 限流的三个层次
L1 防滥用(网关) 按 IP/API Key 粗粒度 QPS —— 挡爬虫与攻击
L2 公平配额(应用) 按 租户/用户 + 端点分级 —— 防大户挤兑,SLA 承诺
L3 防冲击(客户端) 429/Retry-After 驱动退避 —— 与客户端协作重试API 设计规范重点管 L2 的对外契约:算法选择是实现细节(令牌桶/滑动窗口皆可),头部表达才是接口的一部分。
2. 限流头部:从民间约定到标准
2.1 X-RateLimit 旧俗(事实标准,正被替代)
http
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 873
X-RateLimit-Reset: 1727254800 ← 何时重置(Unix 秒)2.2 RateLimit 标准化(IETF HTTPAPI 工作组)
IETF 已推进统一的 RateLimit/RateLimit-Policy 头部结构(结构参数化,取代各家 X- 私有头;Retry-After 则一直是 RFC 9110 正式成员)。设计准则:
http
HTTP/1.1 429 Too Many Requests
Retry-After: 30 ← MUST(429 的 RFC 6585 义务)
RateLimit-Policy: 1000;w=3600 ← 策略窗口:1 小时 1000 次
RateLimit: 1000;w=3600;remaining=0 ← 当前桶状态
Link: <https://docs.example.com/rate-limits>; rel="help"- 数字头部表达"配额";
Retry-After表达"行动指令"(秒数或 HTTP-date)——客户端只需遵守后者。 - 新团队起步建议:至少给
Retry-After(义务)+ 一组配额头(Limit/Remaining/Reset 语义),头部命名团队统一。
3. 限流的 API 设计细节
- 分级配额建模为资源(大客户可见可查):
http
GET /v1/rate-limits/me
{ "policies": [
{ "scope": "default", "limit": 1000, "window": "1h", "remaining": 873 },
{ "scope": "writes", "limit": 200, "window": "1h", "remaining": 150 }
]}- 响应头在成功响应也要发——客户端据此主动节流,而不是撞 429 才知道;
- 429 与 503 的边界:429=你超速(客户端行为问题);503=我过载(服务端容量问题)——重试语义不同(429 尊重 Retry-After,503 更倾向换实例/退避升级);
- 计费型限流(按量调用)把消耗写进响应扩展字段或
Link: rel="meter"文档; - 白名单/内部流量也要打标签——不然压测与监控全被自家限流器干扰。
4. 安全规范:按攻击面逐层加固
4.1 传输层
- 全站 HTTPS,HTTP →
301/308升级;HSTS 预加载; - TLS 1.2+,禁用弱套件(工具:testssl.sh / SSLLabs);
- 内部微服务间也上 mTLS(服务网格托管)——REST 规范不区分内外,信任边界要显式。
4.2 头部安全基线(API 版)
http
Content-Security-Policy: default-src 'none'; frame-ancestors 'none' ← 防 JSON 被嵌入/点击劫持(含浏览器可达的 API)
X-Content-Type-Options: nosniff ← 防内容嗅探(旧浏览器把 JSON 当 HTML)
Referrer-Policy: no-referrer
Cache-Control: no-store ← 敏感响应(认证章/缓存章已反复强调)
Server / X-Powered-By: 移除或最小化
Access-Control-Allow-*: 白名单收紧,禁止 `*` + 凭证组合4.3 CORS 与 REST 的交汇
- 简单请求(GET/HEAD/POST + 安全头部集合)免预检;自定义头(
Idempotency-Key、X-Request-Id)会触发 OPTIONS 预检——OPTIONS 必须免认证响应并缓存预检(Access-Control-Max-Age: 86400); Authorization头跨域携带 = 预检必发,网关 CORS 配置要放Allow-Headers: Authorization, Content-Type, Idempotency-Key。
4.4 OWASP API Security Top 10 对照速查
| 风险 | 典型 API 场景 | 规范级防护 |
|---|---|---|
| API1 越权(BOLA/IDOR) | /users/7 改 ID 看他人数据 | 每个端点做对象级授权(owner/scope 校验),不只靠网关角色 |
| API2 破损的对象属性级授权 | PATCH 任意改 role/balance 只读字段 | DTO 白名单可写字段(见响应结构章);敏感字段独立端点 + 提权流程 |
| API3 无界对象引用 | 深分页/枚举 ID/构造超大 expand | ID 不可猜(UUID/雪花);pageSize 上限;expand 白名单 |
| API4 过度数据暴露 | GET 返回整行含敏感列 | 表示分层:列表瘦、详情全、敏感列单独资源+权限 |
| API5 缺失功能级授权 | DELETE 仅前端藏按钮 | 方法级 + 资源级双层校验;405/403 正确区分 |
| API6 批量分配 | 客户端 POST 整个对象含 id/createdAt | 服务端覆盖只读字段(同 API2) |
| API7 注入 | 查询参数拼进 SQL/NoSQL/模板/SSRF(?url= 让服务器去请求内网) | 参数化查询;URL 出站白名单;?sort= 列白名单 |
| API8 安全误配 | CORS *、调试端点裸露、错误回显堆栈 | 配置即代码 + 基线扫描(错误章红线) |
| API9 库存与影子 API | 老版本/内部端点无人知无人管 | OpenAPI 注册中心 + 网关路由清单对账;弃用流程(版本章) |
| API10 未管控的 API 消耗 | 无分页全表拉取、昂贵搜索无限流 | 强制分页;昂贵端点独立配额 + 复杂度预算 |
4.5 输入校验的统一姿势
- schema 校验:OpenAPI/JSON Schema 定义边界(maxLength、pattern、enum、required),网关或框架拦截层自动执行——422 的来源;
- 字符串入库前不信任任何 Unicode 控制字符;正则避免回溯炸弹(ReDoS);
- 文件上传:魔数(magic bytes)+ 大小 + 类型三重校验;下载响应
Content-Disposition: attachment(防 HTML 上传后存储型 XSS)。
5. 可观测性规范(安全的另一半)
http
X-Request-Id: 7f3a-… ← 客户端生成/网关注入,全链路透传,4xx 排障主键
Server-Timing: db;dur=12, total;dur=48 ← 性能预算披露- 审计日志:谁(token sub)、对哪个资源(URI + 方法)、改了什么(diff)、结果(状态码 + traceId)——写操作必审计;
- 监控维度:按端点 × 方法 × 状态码 class 聚合;429/401 突增设告警(攻击与集成故障的信号灯);
- DDoS 前置:CDN/LB 层限速 + 握手成本(如 429 前进一步挑战),别把源站当第一道墙。
6. 本章小结
- 限流是契约:
Retry-After(RFC 义务)+ 配额头部 + 可查询的配额资源——让客户端"会做人"。 - 安全头部小全套:
nosniff、CSP、HSTS、收紧 CORS、最小化Server。 - OWASP API Top 10 的本质是授权与暴露面管理,与本章各规范的接口处:对象级授权(认证章)、字段白名单(响应章)、无界引用(分页章)、影子 API(版本章)。
7. 下一步
进阶篇收官。进入实战篇,从零设计一个博客系统 API → 实战:博客系统 API 设计