多实例部署
单进程里「同一份挑战只能兑换一次」由同步占位保证;进程一多,这条保证就变成了进程级。
会发生什么
| 场景 | 结果 |
|---|---|
| 同一实例重复兑换同一挑战 | 被拒绝 |
| 两个实例各自兑换同一挑战 | 可能都通过 |
| 兑换令牌在有效期内重复使用 | 校验函数不做全局拦截 |
这不是配置错误,而是无状态设计的取舍:为了不引入共享存储,我们放弃了全局一次性。
真正兜底的是什么
- 短时效 — 挑战与令牌都有过期时间,重放窗口很小
- 用途绑定 — 令牌只能用在签发时声明的那张表单
- 签名与专用标记 — 无法伪造,也无法拿会话凭证冒充
- 业务侧限流 — 对同一账号、同一邮箱、全局额度的限制仍然独立生效
如果确实需要全局一次性
那就必须引入实例间共享的存储,并接受随之而来的额外依赖与一次跨网络写入。对本站的场景,这个代价大于收益 —— 我们选择把保证写清楚,而不是假装它存在。
警告
文档口径 — 本站凡提到「一次性」,指的都是兑换这一步,且是进程级。不要把这句话写成「令牌全局一次性」,那会与实现不符。