fix(auth): exchange-code 幂等(短宽限窗),根治首开「登录已过期」

根因:全新浏览器(无 localStorage)下,幸存 iframe 拿到的 code 已被消费(宿主预取/
首屏双渲染中首个已消费但没落地/宿主自己先验一次)→ 第二次 exchange 得 10102 → 无票
可退 → SessionExpired。90aefc7d 只挡了"首个成功落地"的情况,挡不住这种。

改:exchangeCode 首次消费后落一份短期幂等副本(CODE_RESULT_PREFIX,EXCHANGE_GRACE_SECONDS=20s);
同一 code 在宽限窗内重复换返回同一票,不报 10102;过窗即真失效,把可重放窗口压到最小。

模拟宿主(4100)复现 + 验证:已消费 code + 清 localStorage 首开,修复前报「登录已过期」,
修复后工作台正常加载;API 层同一 code 两次 exchange 均返回 code=0。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Found errors in your .gitlab-ci.yml:

  • jobs:openapi-drift config contains unknown keys: rules
You can also test your .gitlab-ci.yml in the Lint
Status Job ID Name Coverage