日期:2026-07-12
标签:#面试 #八股 #后端 #API网关 #安全 #重放攻击
一句话答案
请求携带身份、时间戳、一次性 nonce、幂等键和签名,网关验证时间窗口及签名,并原子记录 nonce 防重复;高价值操作还要绑定请求体和业务状态。
面试口语版
客户端对 method、path、规范化 query、body hash、timestamp、nonce 和 clientId 进行 HMAC/非对称签名。网关先校验凭证和签名,再检查时间戳在允许窗口内,用 Redis SET NX EX 原子记录 clientId:nonce;已存在就拒绝。时间窗口只能限制旧包,nonce 才阻止窗口内重复。业务写接口还携带 idempotencyKey,服务端保存首次结果,防网关状态丢失或合法网络重试造成重复扣款。全链路使用 TLS,密钥定期轮换。
校验流程
flowchart LR
A[请求] --> B[校验身份与时间窗]
B --> C[计算规范化请求签名]
C --> D[Nonce原子去重]
D --> E[业务幂等校验]
E --> F[转发]
关键细节
- 签名必须包含 body hash,否则攻击者可改正文。
- 多节点共享 nonce 状态或使用一致分片,TTL 覆盖时间窗口。
- 客户端时钟漂移需有限容忍并提供校时机制。
- 防重放不等于防 XSS、Token 窃取或越权。
面试官追问
- 只有时间戳为什么不够?
- Redis 挂了 nonce 如何处理?
- 合法请求超时重试会被拒绝吗?
面试官追问参考答案
1. 只有时间戳为什么不够?
攻击者可在允许的几十秒窗口内重复发送同一个有效包,时间戳仍合法。nonce/请求 ID 需要在窗口内只接受一次,业务幂等键进一步保证副作用不重复。
2. Redis 挂了 nonce 如何处理?
按风险分级:支付等高风险接口 fail-close 或切高可用去重存储,普通读可降级。本地缓存只能防单节点重复,无法保证全局;Redis 集群需跨故障域并保留容量告警。
3. 合法请求超时重试会被拒绝吗?
网络层 nonce 重试可以使用新 nonce,但业务 idempotencyKey 保持不变,服务端返回首次执行结果。也可允许同 nonce 返回缓存结果而不再次执行,协议需明确。
学习清单
- 掌握 timestamp、nonce、签名和业务幂等。
- 理解高风险接口的故障策略。