3.2 KiB
3.2 KiB
修复登录无限循环(登录成功后弹回登录页)
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 逻辑完整)。
第二步:配套校验与清理
- 核对
yz_auth_client表 yz-backend 的 redirect_uris 白名单包含http://127.0.0.1:4401/auth-callback.html(不匹配则用 MySQL MCP 补登) - 清理脏数据:将 hero920103(identity_id=2)名下 revoked=0 的旧会话标记 revoked=1(reason='cleanup'),避免旧会话占用互踢名额
- 重启 Vite dev server 使 env 生效
- 验证本地登录页 HTML 表单嵌入 client_id(curl 抓取确认,防止空 client 会话再现)
第三步:端到端验证
- 无痕窗口(避免残留 localStorage token/userInfo)访问
http://127.0.0.1:4401 - 完整走:跳本地登录页 → 输入 hero920103 → 企业选择(展示 2 家)→ 选 tid=2 → 回跳 auth-callback → 进入工作台,无循环
- MySQL MCP 复查
yz_auth_session无异常互踢 - 登录恢复后,验证原任务功能:apps/oa/schedule 日历按 hero920103 排班显示上班(绿)/休息(橙)背景(后端
/backend/oa/scheduling/my已就绪)
涉及文件
backend/.env.development(唯一代码修改:VITE_AUTH_BASE 指向本地)- 数据库:
yz_auth_client(白名单核对)、yz_auth_session(脏数据清理) - 不改 Go 代码(互踢规则是合理安全设计;根因是开发环境认证指向了旧版远程中心)