Commit 7196ad06 by luoqi

merge: fix/refresh-single-flight → test(冷启动换票走共享单飞)

parents 504b0e19 2207d61b
Pipeline #3585 failed in 0 seconds
......@@ -2,7 +2,7 @@
import { useEffect, useRef, useState } from 'react';
import { useAuthStore } from '@/stores/auth-store';
import { exchangeCode, refreshToken } from '@/lib/auth-api';
import { exchangeCode } from '@/lib/auth-api';
import { tryRefresh } from '@/lib/api-client';
import { env } from '@/lib/env';
......@@ -195,20 +195,33 @@ export function useAuthBootstrap() {
}
// ─── 3. 仅 refresh token 还在 → silent refresh ───
//
// 🔴 **必须走 api-client 的共享单飞 `tryRefresh`**,⛔ 不能直接调 `refreshToken()`。
// refresh token 是**一次性**的:服务端换票时 `redis.del(旧 jti)` 再发新的
// (auth.service.ts:468)。所以同一张票被两条路各换一次,后到的那条必得
// `10103 AUTH_INVALID_REFRESH_TOKEN` → 前端据此清会话 → 「登录已过期」。
//
// ── 2026-08-20 生产实录(client-diag)────────────────────────
// ev=start accessValid=N ← access 到点过期
// ev=refresh-ok ← 本函数直接换,成功,旧 jti 已作废
// ev=runtime-refresh-fail err=code=10103 ← 首屏请求 401 兜底刷,拿的是同一张旧票
// ev=runtime-auth-clear err=code=10106 ← 清凭据,弹「登录已过期」
// 主管当时什么都没做错,只是隔了 2 小时回到页面。
//
// ⚠️ 下面那个"过期前 60s 定时刷"**早就改成走单飞了**(见本文件末尾那段注释,
// 同一条根因),⛔ 唯独这里漏了 —— 而这里恰恰是**每次冷启动**都会走的路径,
// 比定时器常见得多。
if (s.refreshToken) {
setStatus('authenticating');
try {
const r = await refreshToken(s.refreshToken);
setTokens(r);
const ok = await tryRefresh(); // 成功即 setTokens、失败即 clear,内部已处理
if (ok) {
reportDiag({ ev: 'refresh-ok', codeTag });
setStatus('ready');
return;
} catch {
} else {
reportDiag({ ev: 'refresh-fail', codeTag, ...storeSnap(), ...envInfo });
clear();
setStatus('error');
return;
}
return;
}
// ─── 4. 全没了 → 弹「登录已过期」───
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment