# 修复登录无限循环(登录成功后弹回登录页) ## Context(问题与证据链) 用户反馈:登录成功后又回到登录界面,无限循环。排查已确认(含用户亲证): **用户确认的现象** - 登录页地址栏为 `api.yunzer.cn`(远程线上认证中心,非本地 9000) - 登录后见过「选择要进入的企业」界面(hero920103 绑定 2 家企业),**选完企业后又弹回登录页** **数据库证据(go-platform 库)** - hero920103 = identity_id 2(李志强),绑定两家企业(tid=1、tid=2)→ 登录必走"待选企业"分支 - `yz_auth_session`:18:09~18:12 连续 4 条会话被踢(revoked=1, revoke_reason='kicked');最新会话 id=386(18:18:29,tid=2,client_id 为空) - 18:24:42 登录日志(id=218,user_id=1)与 hero920103 实际 identity_id=2 不符 → **该日志由远程旧版代码写入**(字段语义不同),且 IP=127.0.0.1/::1 符合"远程 nginx 反代回环"特征 **代码机制(go/services/auth/session.go L61-134)** - `CreateSession` 按 identity_id **全局**统计活跃会话,超 MaxSession 即踢最旧会话(kicked),不区分 tid/client/服务实例 - 登录 → 远程建会话 → 企业选择 → 新会话又创建 → 互踢 → authorize 发现会话已吊销 → 送回登录页 → 再登录 → **无限循环** - 远程为旧版代码(字段错位可证),其企业选择后的会话处理存在缺陷,无法本地修复 ## 修复方案 ### 第一步:本地开发认证切换到本地 9000 实例(核心修复) 修改 `backend/.env.development`: ``` VITE_AUTH_BASE='http://127.0.0.1:9000/auth' ``` 本地 9000 已注册全套认证端点(/auth/login、/auth/authorize、/auth/token、/auth/userinfo、/auth/switch-tenant,见 `go/routers/auth/auth.go`),且为最新代码(企业选择、cookie、PKCE 逻辑完整)。 ### 第二步:配套校验与清理 1. 核对 `yz_auth_client` 表 yz-backend 的 redirect_uris 白名单包含 `http://127.0.0.1:4401/auth-callback.html`(不匹配则用 MySQL MCP 补登) 2. 清理脏数据:将 hero920103(identity_id=2)名下 revoked=0 的旧会话标记 revoked=1(reason='cleanup'),避免旧会话占用互踢名额 3. 重启 Vite dev server 使 env 生效 4. 验证本地登录页 HTML 表单嵌入 client_id(curl 抓取确认,防止空 client 会话再现) ### 第三步:端到端验证 1. 无痕窗口(避免残留 localStorage token/userInfo)访问 `http://127.0.0.1:4401` 2. 完整走:跳本地登录页 → 输入 hero920103 → 企业选择(展示 2 家)→ 选 tid=2 → 回跳 auth-callback → 进入工作台,无循环 3. MySQL MCP 复查 `yz_auth_session` 无异常互踢 4. 登录恢复后,验证原任务功能:apps/oa/schedule 日历按 hero920103 排班显示上班(绿)/休息(橙)背景(后端 `/backend/oa/scheduling/my` 已就绪) ## 涉及文件 - `backend/.env.development`(唯一代码修改:VITE_AUTH_BASE 指向本地) - 数据库:`yz_auth_client`(白名单核对)、`yz_auth_session`(脏数据清理) - 不改 Go 代码(互踢规则是合理安全设计;根因是开发环境认证指向了旧版远程中心)