--- id: T-226 title: Go ERP 会话管理与 Admin 验证码登录 phase: 2 deps: - T-225 status: TODO created: 2026-07-29 context_ref: d62a4af work_branch: null write_paths: - docs/tasks/T-226.md - docs/04-architecture.md - docs/api.md - docs/routes.md - docs/current-state.md - backend-api/internal/config/** - backend-api/internal/platform/shunyunbao/** - backend-api/internal/transport/httpapi/** - backend-api/internal/transport/webui/** - backend-api/cmd/api/** --- ## 问题 / 背景 直接 Go 查询需要让后端在同一 ERP 会话中获取验证码、登录、验证状态和发起查询。账号 密码不能输入到普通 Admin 表单,Cookie/JWT 不能发给浏览器;同时单机验证版不需要为 恢复会话额外部署 Redis。 ## 关联需求与交互 - 功能:F-011。 - 用户故事:US-011。 - 交互:IX-012 增加 ERP 连接状态、获取验证码和提交验证码。 - 架构:一个受互斥保护的 Go 会话管理器服务一个受配置 ERP 账号;进程重启后会话失效, 需要人员重新登录。 ## 方案 1. ERP base URL、用户名和密码只从后端启动环境读取;不读取 `.env`,不保存到 SQLite、 Cookie、浏览器、普通日志或 API 响应。 2. Admin 连接页显示匿名会话状态,可请求一次性验证码图片并输入验证码登录。图片响应 必须 `no-store`,浏览器只得到验证码图片和短期 ticket,不能得到 ERP Cookie/JWT。 3. 会话管理器为 Cookie jar、token、用户最小标识和 ticket 建立串行锁;查询、验证码 和登录不能并发改变同一会话。 4. 账号/密码未配置、验证码过期、登录拒绝、会话过期和 ERP 不可用均返回稳定匿名错误。 5. 首版只保留内存会话;加密持久化会话须另立任务,不引入 Redis。 ## 验收要点 - [ ] 配置缺失、验证码获取、错误/过期验证码、登录成功、会话过期和并发请求有单元/HTTP 测试。 - [ ] Admin 页面在桌面和手机视口显示状态、验证码和可修复错误,不显示密码、Cookie、JWT 或验证码文本。 - [ ] 会话请求和查询共享同一受控 Cookie jar;进程重启后明确要求重新登录。 - [ ] `go test ./...`、`go vet ./...` 通过;不访问线上 ERP。 ## 边界 - 不自动 OCR、猜测或绕过验证码。 - 不实现多 ERP 账号、多租户、Redis 或凭证 Web 编辑。 - 不切换货运同步查询源;属于 T-227。 ## 执行记录 - 2026-07-29:由 T-225 依赖创建,等待协议契约完成。