2.4 KiB
2.4 KiB
Session restore 每日登录埋点案例(2026-05-08)
现象
用户反馈:已经登录且 cookie 没过期时,打开网页没有触发每日登录埋点。
根因
当本地 access token 仍有效时,前端 AuthGate 恢复登录态只会复用现有 token 并请求 /api/auth/me。/api/auth/me 只读取当前用户,不会进入 POST /api/auth/session/refresh,因此后端 refresh handler 中的每日登录埋点不会执行。
关键误判点:后端已经在 refresh cookie 续期写埋点,不等于“打开网页”一定会触发。前端必须实际调用 refresh/session 接口。
修复模式
- 在
src/services/apiClient.ts暴露强制 refresh 方法,例如:
export async function refreshStoredAccessToken() {
return refreshAccessToken();
}
- 在
src/components/auth/AuthGate.tsx的 hydrate/restore 中,使用:
await refreshStoredAccessToken();
const nextSession = await getCurrentAuthUser();
而不是只调用:
await ensureStoredAccessToken();
const nextSession = await getCurrentAuthUser();
-
保留
ensureStoredAccessToken()给普通受保护请求兜底;不要把所有请求都改成强制 refresh。 -
确认
server-rs/crates/api-server/src/refresh_session.rs在 rotate refresh session 成功且新 access token 签发成功后调用每日登录埋点 helper。 -
确认
server-rs/crates/spacetime-module/src/runtime/profile.rs中get_profile_task_center不再顺手写daily_login,避免任务中心读取污染登录埋点。
测试
前端测试重点:
AuthGate会等待refreshStoredAccessToken()完成后才暴露已恢复用户内容。AUTH_STATE_EVENT触发 hydrate 时仍保持已挂载平台内容和本地 tab 状态。
命令:
npm run test -- AuthGate.test.tsx
npm run typecheck
后端/SpacetimeDB 编译:
cd server-rs && cargo check -p spacetime-module
cd server-rs && cargo check -p api-server
全局检查:
npm run check:encoding
git diff --check
注意
- Vitest 0.34 不支持 Jest 的
--runInBand参数;命令里不要加。 - 埋点失败只能 warning,不能阻断登录态恢复。
- 如果后续发现打开页面产生过多 refresh 请求,需要在产品口径和埋点口径之间重新设计节流;但不能退回“只读
/api/auth/me却期待写登录埋点”的状态。