fix(web): 修复登录时序bug - token先存localStorage再取用户信息 #734

Merged
xiaoxia merged 1 commits from fix/login-token-order-bug into develop 2026-07-22 22:42:09 +08:00
Owner
No description provided.
xiaoxia added 1 commit 2026-07-22 18:45:41 +08:00
fix(web): 修复登录时序bug - token先存localStorage再取用户信息
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 53s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 42s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 38s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m2s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 2m37s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 1m10s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 56s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m29s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Failing after 1m24s
AI Code Review / AI Code Review (pull_request) Successful in 5m29s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 9m43s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 17m33s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 29s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 2m20s
a22fa257f1
登录流程中,getCurrentUser() 在 setAuth() 之前执行,
导致 apiClient 请求拦截器从 localStorage 取不到 token,
请求不带 Authorization header,后端返回 401,
触发自动刷新逻辑后 clearAuth 跳回登录页。

修复:先把 token 存到 localStorage,再调 getCurrentUser,
最后 setAuth 同步 store 状态。

影响:useLogin / useWechatCallback 两个 hook
auto-approve-bot approved these changes 2026-07-22 19:19:38 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-07-22 19:19:39 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。

🚀 预览环境已部署

项目 详情
PR号 #734
预览链接 https://pr-734.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #734 | | 预览链接 | [https://pr-734.preview.xiaoxiajianji.com](https://pr-734.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
Collaborator

📊 审查概览

  • 整体评价:需修改
  • 严重问题数量:1 个
  • 一般建议数量:2 个

需修改的问题(严重)

  1. [apps/web/src/hooks/useAuth.ts: 23-30 & 64-71] 异常处理导致状态不一致
    • 问题描述:代码在调用 authApi.getCurrentUser() 之前先将 token 写入了 localStorage。如果 getCurrentUser() 请求失败(例如网络错误、服务器 500 或 Token 实际无效),函数会抛出异常并终止,导致后续的 setAuth() 不会被调用。此时,localStorage 中残留了有效的 access_token,但应用内存状态(Context/State)中并未记录用户已登录。
    • 后果:这会导致“僵尸”会话。用户虽然看到登录失败,但刷新页面后,应用初始化逻辑可能会检测到 localStorage 中有 token 从而误判为已登录,或者因为缺少用户信息而导致后续逻辑错误。
    • 修改建议:确保在 getCurrentUser() 失败时回滚 token 的写入。可以使用 try...catch 包裹 getCurrentUser,在 catch 块中清除 token,或者利用 try...finally 确保资源清理。

💡 改进建议(一般)

  1. [apps/web/src/hooks/useAuth.ts: 23-26 & 64-67] 代码重复

    • 具体内容:将 access_tokenrefresh_token 存入 localStorage 的逻辑在 useLoginuseWechatCallback 两个函数中完全重复。建议提取为一个私有辅助函数(如 persistTokens),以提高可维护性并避免未来修改时遗漏。
  2. [apps/web/src/hooks/useAuth.ts: 31 & 72] 潜在的重复写入

    • 具体内容:代码手动调用了 localStorage.setItem,随后又调用了 setAuth。需要确认 setAuth 函数的内部实现。如果 setAuth 内部也会将 token 同步写入 localStorage,则此处存在冗余的 I/O 操作。建议明确 setAuth 的职责边界(仅更新内存状态 vs 持久化存储),避免职责不清。

良好实践

  • 修复竞态条件:PR 正确地识别了 apiClient 拦截器依赖 localStorage 的问题,通过调整写入顺序解决了 getCurrentUser 请求无法携带 Authorization header 的逻辑缺陷。
  • 空值保护:在存储 refresh_token 前进行了 if (refreshToken) 判断,避免了存入 nullundefined 字符串。

🤖 由 AI 代码审查机器人自动生成 | 2026-07-22 19:23:57 | 模型:

### 📊 审查概览 - **整体评价**:需修改 - **严重问题数量**:1 个 - **一般建议数量**:2 个 ### ❌ 需修改的问题(严重) 1. **[apps/web/src/hooks/useAuth.ts: 23-30 & 64-71] 异常处理导致状态不一致** - **问题描述**:代码在调用 `authApi.getCurrentUser()` 之前先将 token 写入了 `localStorage`。如果 `getCurrentUser()` 请求失败(例如网络错误、服务器 500 或 Token 实际无效),函数会抛出异常并终止,导致后续的 `setAuth()` 不会被调用。此时,`localStorage` 中残留了有效的 access_token,但应用内存状态(Context/State)中并未记录用户已登录。 - **后果**:这会导致“僵尸”会话。用户虽然看到登录失败,但刷新页面后,应用初始化逻辑可能会检测到 localStorage 中有 token 从而误判为已登录,或者因为缺少用户信息而导致后续逻辑错误。 - **修改建议**:确保在 `getCurrentUser()` 失败时回滚 token 的写入。可以使用 `try...catch` 包裹 `getCurrentUser`,在 catch 块中清除 token,或者利用 `try...finally` 确保资源清理。 ### 💡 改进建议(一般) 1. **[apps/web/src/hooks/useAuth.ts: 23-26 & 64-67] 代码重复** - **具体内容**:将 `access_token` 和 `refresh_token` 存入 `localStorage` 的逻辑在 `useLogin` 和 `useWechatCallback` 两个函数中完全重复。建议提取为一个私有辅助函数(如 `persistTokens`),以提高可维护性并避免未来修改时遗漏。 2. **[apps/web/src/hooks/useAuth.ts: 31 & 72] 潜在的重复写入** - **具体内容**:代码手动调用了 `localStorage.setItem`,随后又调用了 `setAuth`。需要确认 `setAuth` 函数的内部实现。如果 `setAuth` 内部也会将 token 同步写入 `localStorage`,则此处存在冗余的 I/O 操作。建议明确 `setAuth` 的职责边界(仅更新内存状态 vs 持久化存储),避免职责不清。 ### ✅ 良好实践 - **修复竞态条件**:PR 正确地识别了 `apiClient` 拦截器依赖 `localStorage` 的问题,通过调整写入顺序解决了 `getCurrentUser` 请求无法携带 Authorization header 的逻辑缺陷。 - **空值保护**:在存储 `refresh_token` 前进行了 `if (refreshToken)` 判断,避免了存入 `null` 或 `undefined` 字符串。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-07-22 19:23:57 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia merged commit fcdf693707 into develop 2026-07-22 22:42:09 +08:00

🗑️ 预览环境已清理

PR #734 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #734 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.