前端把某些高负载下的鉴权失败当成了“登录失效”,然后清空 token 并跳转登录页
核心链路是:
-
控制台登录/进入页面后会立刻请求当前用户信息
frontend/src/stores/auth.ts:117 的 checkAuth() 会加载本地 token 后立即 refreshUser(),也就是打 /auth/me。
另外 frontend/src/stores/auth.ts:362 的 setToken() 也会立刻拉一次用户信息。
-
任何接口返回 401,前端都会尝试刷新 token
逻辑在 frontend/src/api/client.ts:151。
如果刷新失败,前端会清空 auth_token、refresh_token、auth_user,然后跳转 /login:
frontend/src/api/client.ts:222
-
高负载时,后端鉴权中间件可能把数据库/服务异常误判成 401 USER_NOT_FOUND
这里是最可疑点。
backend/internal/server/middleware/jwt_auth.go:60 里 userService.GetByID() 只要报错,就直接返回 401 USER_NOT_FOUND。
管理端鉴权也一样:backend/internal/server/middleware/admin_auth.go:171
也就是说,高负载时如果查用户超时、数据库连接池打满、查询失败,这里没有区分“用户真的不存在”和“数据库临时不可用”,而是统一返回 401。前端收到 401 后会走刷新 token;如果刷新也失败,就直接
清 token 自动登出。
还有一个放大因素:/auth/refresh 本身加了 Redis 限流,而且是 fail-close:
- 路由限流在 backend/internal/server/routes/auth.go:42
- Redis/限流异常时会返回 429,见 backend/internal/middleware/rate_limiter.go:99
- 刷新 token 还会访问 Redis 和数据库,见 backend/internal/service/auth_service.go:1500
所以高负载下可能是:
/auth/me 查用户失败 -> 返回 401 -> 前端刷新 token -> /auth/refresh 因 Redis/DB/限流失败 -> 前端清空登录态 -> 自动回登录页。
建议:
- 后端鉴权中间件不要把 GetByID 的所有错误都返回 401。只有用户不存在、禁用、token version 不匹配才返回 401;数据库超时/连接失败应该返回 503 或 500。
- 前端刷新 token 失败时,不要对 429/500/503/network error 直接清空登录态。这些更像临时服务异常,应该保留 token,提示稍后重试。
前端把某些高负载下的鉴权失败当成了“登录失效”,然后清空 token 并跳转登录页
核心链路是:
控制台登录/进入页面后会立刻请求当前用户信息
frontend/src/stores/auth.ts:117 的 checkAuth() 会加载本地 token 后立即 refreshUser(),也就是打 /auth/me。
另外 frontend/src/stores/auth.ts:362 的 setToken() 也会立刻拉一次用户信息。
任何接口返回 401,前端都会尝试刷新 token
逻辑在 frontend/src/api/client.ts:151。
如果刷新失败,前端会清空 auth_token、refresh_token、auth_user,然后跳转 /login:
frontend/src/api/client.ts:222
高负载时,后端鉴权中间件可能把数据库/服务异常误判成 401 USER_NOT_FOUND
这里是最可疑点。
backend/internal/server/middleware/jwt_auth.go:60 里 userService.GetByID() 只要报错,就直接返回 401 USER_NOT_FOUND。
管理端鉴权也一样:backend/internal/server/middleware/admin_auth.go:171
也就是说,高负载时如果查用户超时、数据库连接池打满、查询失败,这里没有区分“用户真的不存在”和“数据库临时不可用”,而是统一返回 401。前端收到 401 后会走刷新 token;如果刷新也失败,就直接
清 token 自动登出。
还有一个放大因素:/auth/refresh 本身加了 Redis 限流,而且是 fail-close:
所以高负载下可能是:
/auth/me 查用户失败 -> 返回 401 -> 前端刷新 token -> /auth/refresh 因 Redis/DB/限流失败 -> 前端清空登录态 -> 自动回登录页。
建议: