Skip to content

限流与安全规范

本章导读:限流不是运维的 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 设计细节

  1. 分级配额建模为资源(大客户可见可查):
http
GET /v1/rate-limits/me
{ "policies": [
    { "scope": "default",  "limit": 1000, "window": "1h", "remaining": 873 },
    { "scope": "writes",   "limit": 200,  "window": "1h", "remaining": 150 }
]}
  1. 响应头在成功响应也要发——客户端据此主动节流,而不是撞 429 才知道;
  2. 429 与 503 的边界:429=你超速(客户端行为问题);503=我过载(服务端容量问题)——重试语义不同(429 尊重 Retry-After,503 更倾向换实例/退避升级);
  3. 计费型限流(按量调用)把消耗写进响应扩展字段或 Link: rel="meter" 文档;
  4. 白名单/内部流量也要打标签——不然压测与监控全被自家限流器干扰。

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-KeyX-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/构造超大 expandID 不可猜(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 设计