开放 API 只校验 Token 够吗?签名、防重放与 IP 白名单设计
开放 API 只校验 Token 够吗?签名、防重放与 IP 白名单设计内容摘要:开放 API 只验证一个长期 Token,无法证明请求参数是否被修改,也无法限制合法请求被重复提交。本文结合 MetaLite 当前源码,拆解调用方身份、固定顺序摘要、30 秒时间窗口、IP 白名单与限流如何组成一条认证链,并说明现有实现的能力边界。一个合法请求被完整复制后,在30秒内再次发送,网关应该放行还是拒绝?这不是一道纯理论题。订单创建、余额变更、发券等写接口一旦被重复调用,后果往往比一次普通的认证失败更严重。本文重点回答三个问题:为什么只有appId + Token仍然不够;MetaLite 当前源码实际签了哪些字段、按什么顺序执行;时间戳、IP 白名单能解决什么,又不能解决什么。一、开放 API 的认证困境当微服务系统需要对外提供 API 时,面临的第一道难题就是:如何安全地识别调用方身份,并防止请求被篡改或重放?传统的做法是使用 HTTP Basic Auth 或简单的 Token 认证。但这些方案存在明显的安全短板:凭证泄露:长期凭证一旦泄露,攻击者可以在凭证被轮换、吊销或过期前持续使用。请求重放:TLS 能显著降低传输链路被窃听和篡改的风险,但无法替代服务端的幂等与防重放控制。请求篡改:如果认证范围不覆盖请求参数,服务端无法判断收到的业务内容是否与调用方发送时一致。常见做法是让调用方对规范化后的请求内容计算认证值,服务端按同一规则复算并比较。MetaLite 当前实现使用 SM3 或 SHA-256 对固定顺序的字段和共享盐值计算摘要,再叠加时间窗口、IP 白名单与调用方限流。需要先明确边界:当前实现属于共享秘密参与的请求摘要校验,项目字段和方法名沿用了sign、checkSign。它不是基于公私钥的数字签名,也不是标准 HMAC。对安全等级更高的开放平台,后续应优先扩展 HMAC-SHA-256、HMAC-SM3 或非对称签名,并配合密钥轮换。二、认证架构总览MetaLite 的调用方认证系统以CallerAuthService为核心:ExternalReq (appId + timestamp + sign + ...) │ ▼ CallerAuthHandler.preHandle() │ ▼ CallerAuthService.authApp(req) │ ├── 1. 检查调用方是否存在且启用 ├── 2. 检查时间戳是否在 30 秒窗口内 ├── 3. 检查请求 IP 是否在白名单中 ├── 4. 验证请求签名 (SM3 / SHA-256) └── 5. 调用方级别限流 (Redis Lua 脚本)认证流程通过CallerAuthHandler进入网关处理器链,减少 Controller 中的重复校验代码;调用方配置、处理器顺序和异常返回仍需业务与运维共同维护。@Component