Files
cmautobuy/docs/task/50-admin-首次管理员初始化与网页登录.md
T
2026-08-09 13:37:23 +08:00

4.4 KiB
Raw Blame History

50 Admin:实现首次管理员初始化与网页登录

背景与目标

Admin 原有全部网页都可匿名访问,也没有管理员初始化、登录或退出能力。本任务 建立最小且完整的网页登录边界:首次运行由操作员创建唯一的首位管理员,随后 所有业务网页必须凭服务端 Session 访问,同时保持 Client API 的现有调用方式不变。

最终方案

  • 新增 v6 迁移,在末尾追加 users 和 web_sessions,未改写 v1–v5;用户名 使用不区分大小写的唯一约束,角色和状态使用固定值约束。
  • /setup 仅在用户表为空时开放;创建管理员前在写事务内再次检查,两个并发 初始化请求最多一个成功。入口一旦关闭,即使账号以后禁用也不会重新开放。
  • 密码使用 bcrypt 默认成本哈希,服务层校验至少 8 个字符和 bcrypt 的 72 字节 上限;数据库、页面及日志均不保存或回显明文密码。
  • 登录成功生成 32 字节密码学随机 Token,浏览器 Cookie 保存原文,数据库只保存 SHA-256。Session 固定 12 小时有效,退出和账号禁用会使旧 Session 失效。
  • 认证 Cookie 使用 HttpOnly、SameSite=Lax、Path=/,HTTPS 请求自动增加 Secure;登录后的 next 只接受本站绝对路径,阻止开放重定向。
  • Web 公开页和业务页都经过 CSRF;认证中间件只挂业务网页路由组。Client API 继续注册在独立路由组,不要求网页登录 Cookie,也不经过浏览器 CSRF。
  • 增加独立初始化页和登录页;业务导航显示当前用户名,并用 POST 表单退出。

实际实现与工单确认方案一致。采购员管理、密码重置和登录限速留给 #51,Client API Key 认证留给 #52,本任务没有扩大范围。

改了哪些

  • admin/repository/db.go、admin/model/model.go、admin/repository/user.go: v6 数据结构、用户与 Session 数据访问及初始化事务。
  • admin/service/auth.go:首次初始化、bcrypt 密码校验、登录认证、Session 哈希与退出。
  • admin/handler/web/auth.go、admin/handler/web/web.go:公开认证页、业务页中间件、 Cookie、本站回跳和退出路由。
  • admin/templates/auth/、admin/templates/partials/header.html、 admin/static/css/app.css:初始化、登录和已登录导航界面。
  • admin/auth_integration_test.go、admin/handler/web/auth_test.go、 admin/service/auth_test.go、admin/repository/migrate_test.go、admin/main_test.go: 迁移、并发、安全属性、HTTP 完整流程和回归测试。
  • docs/admin/03-data-model.md:将 v6 用户与 Session 模型从规划更新为已实现。

验收结果

验收标准 结果
v6 可从全新库和历史结构升级,且未改写旧迁移 通过
首次初始化并发请求最多创建一个管理员 通过
初始化完成后 /setup 永久关闭 通过
密码只保存 bcrypt 哈希,错误凭据统一提示 通过
Session 原文不入库,固定 12 小时过期 通过
退出、过期和账号禁用后旧 Session 失效 通过
Cookie 具备 HttpOnly、SameSite、Path 和 HTTPS Secure 属性 通过
登录回跳不能跳往外部网站 通过
所有 Web POST 均经过 CSRF 通过
Client API 不经过网页登录与浏览器 CSRF 通过
1366×768 初始化、登录及已登录导航布局 通过
Go 1.23.0 全量检查 通过

测试

  • 执行的命令:

    cd D:\chengma\cmautobuy\admin
    gofmt -l .
    go vet ./...
    go build ./...
    go test ./... -count=1
    
  • 结果:Go 版本为 go1.23.0 windows/amd64;全部通过,gofmt -l . 无输出。

  • 浏览器验证:使用隔离的临时数据库,在 1366×768 完成 /setup 初始化、/login 登录并进入 /shopee;表单标签、密码框、提示、用户名和退出按钮均正常。

  • 没验证到的部分:没有在真实 HTTPS 服务上手工检查浏览器 Cookie,Secure 属性由带 TLS 请求的单元测试覆盖;没有触发真实采集或采购。

相关提交

  • 0a7db40 feat: 实现 Admin 首次初始化与网页登录 (#50)