# 实现任务清单 **Change ID**: `implement-b-end-auth-system` --- ## 阶段 1:基础设施 (2-3 小时) ### Task 1.1: 创建 Token 管理器 **文件**: `pkg/auth/token.go` **实现内容**: - [x] 定义 `TokenManager` 结构体 - [x] 定义 `TokenInfo` 结构体(包含用户信息) - [x] 实现 `GenerateTokenPair()`:生成 access token 和 refresh token - [x] 实现 `ValidateAccessToken()`:验证 access token - [x] 实现 `ValidateRefreshToken()`:验证 refresh token - [x] 实现 `RefreshAccessToken()`:刷新 access token - [x] 实现 `RevokeToken()`:撤销单个 token - [x] 实现 `RevokeAllUserTokens()`:撤销用户的所有 token **验证**: - [x] 单元测试覆盖所有方法 - [x] Redis 连接失败时正确处理错误 - [x] Token 生成使用 UUID v4 - [x] Token 存储和查询正确 **依赖**: Redis 客户端 --- ### Task 1.2: 创建认证常量 **文件**: `pkg/constants/auth.go` **实现内容**: - [x] 添加 `RedisAuthTokenKey()` 函数 - [x] 添加 `RedisRefreshTokenKey()` 函数 - [x] 添加 `RedisUserTokensKey()` 函数 - [x] 添加默认 Token TTL 常量 **验证**: - [x] Redis key 格式正确 - [x] 无硬编码字符串 --- ### Task 1.3: 扩展错误码 **文件**: `pkg/errors/codes.go` **实现内容**: - [x] 添加 `CodeInvalidCredentials = 1010`:用户名或密码错误 - [x] 添加 `CodeAccountDisabled = 1011`:账号已禁用 - [x] 添加 `CodeAccountLocked = 1012`:账号已锁定 - [x] 添加 `CodePasswordExpired = 1013`:密码已过期 - [x] 添加 `CodeInvalidOldPassword = 1014`:旧密码错误 - [x] 在 `codeMessages` 和 `codeLevels` 中添加中文消息和日志级别 **验证**: - [x] 所有新增错误码有对应的中文消息 - [x] 错误码不与现有冲突 --- ## 阶段 2:数据访问层 (1-2 小时) ### Task 2.1: 扩展 AccountStore **文件**: `internal/store/postgres/account_store.go` **实现内容**: - [x] 添加 `GetByUsername()`:根据用户名查询账号 - [x] 添加 `GetByUsernameOrPhone()`:根据用户名或手机号查询 - [x] 确保查询包含软删除检查(`deleted_at IS NULL`) **验证**: - [x] 查询条件正确 - [x] 单元测试覆盖新增方法 - [x] 已禁用账号无法查询 **依赖**: 无(已存在 AccountStore) --- ## 阶段 3:业务逻辑层 (4-6 小时) ### Task 3.1: 创建认证服务 **文件**: `internal/service/auth/service.go` **实现内容**: - [x] 定义 `Service` 结构体(注入 `AccountStore`、`TokenManager`、`Logger`) - [x] 定义 `LoginRequest`、`LoginResponse` DTO - [x] 实现 `Login()`:账号密码登录 - [ ] 根据用户名查询账号 - [ ] 验证密码(bcrypt.CompareHashAndPassword) - [ ] 检查账号状态(status=1) - [ ] 生成 token 对 - [ ] 查询用户权限列表(调用 permission service) - [ ] 返回 token 和用户信息 - [x] 实现 `Logout()`:登出 - [ ] 撤销 access token - [ ] 撤销 refresh token - [x] 实现 `RefreshToken()`:刷新 token - [ ] 验证 refresh token - [ ] 生成新的 access token - [x] 实现 `GetCurrentUser()`:获取当前用户信息和权限 - [x] 实现 `ChangePassword()`:修改密码 - [ ] 验证旧密码 - [ ] 哈希新密码 - [ ] 更新数据库 - [ ] 撤销所有旧 token **验证**: - [x] 单元测试覆盖所有方法 - [x] 登录失败场景正确处理(密码错误、账号禁用) - [x] 密码修改后旧 token 失效 - [x] 错误消息清晰 **依赖**: Task 1.1(Token 管理器)、Task 2.1(AccountStore) --- ### Task 3.2: 创建认证 DTO **文件**: `internal/model/auth_dto.go` **实现内容**: - [x] 定义 `LoginRequest` 结构体(username, password, device) - [x] 定义 `LoginResponse` 结构体(access_token, refresh_token, user, permissions) - [x] 定义 `RefreshTokenRequest` 结构体(refresh_token) - [x] 定义 `RefreshTokenResponse` 结构体(access_token) - [x] 定义 `ChangePasswordRequest` 结构体(old_password, new_password) - [x] 添加 Validator 标签 **验证**: - [x] 所有字段包含 JSON 标签 - [x] 必填字段包含 validate 标签 - [x] 字段注释清晰(中文) **依赖**: 无 --- ## 阶段 4:HTTP 处理层 (3-4 小时) ### Task 4.1: 创建后台认证 Handler **文件**: `internal/handler/admin/auth.go` **实现内容**: - [x] 定义 `AuthHandler` 结构体(注入 `AuthService`) - [x] 实现 `Login()`:POST /api/admin/login - [ ] 解析请求体 - [ ] 验证请求参数 - [ ] 调用 `authService.Login()` - [ ] 返回统一响应格式 - [x] 实现 `Logout()`:POST /api/admin/logout - [ ] 从 header 提取 token - [ ] 调用 `authService.Logout()` - [x] 实现 `RefreshToken()`:POST /api/admin/refresh-token - [ ] 解析请求体 - [ ] 调用 `authService.RefreshToken()` - [x] 实现 `GetMe()`:GET /api/admin/me - [ ] 从 context 获取 userID - [ ] 调用 `authService.GetCurrentUser()` - [x] 实现 `ChangePassword()`:PUT /api/admin/password - [ ] 解析请求体 - [ ] 调用 `authService.ChangePassword()` **验证**: - [x] 所有 Handler 返回统一的 JSON 格式 - [x] 错误处理正确(使用 AppError) - [x] 请求参数验证完整 - [x] 响应包含正确的 HTTP 状态码 **依赖**: Task 3.1(认证服务)、Task 3.2(DTO) --- ### Task 4.2: 创建 H5 认证 Handler **文件**: `internal/handler/h5/auth.go` **实现内容**: - [x] 复制 `admin/auth.go` 的实现 - [x] 修改路由前缀为 `/api/h5/*` - [x] 其他逻辑完全相同 **验证**: - [x] 功能与后台 Handler 一致 - [x] 路由前缀正确 **依赖**: Task 4.1(后台 Handler) --- ## 阶段 5:路由和中间件配置 (2-3 小时) ### Task 5.1: 配置后台认证中间件 **文件**: `internal/bootstrap/middlewares.go` **实现内容**: - [x] 创建 `TokenManager` 实例(注入 Redis、配置) - [x] 创建后台认证中间件(使用 `pkg/middleware/auth.go` 的 `Auth()`) - [x] 配置 `TokenValidator` 函数 - [ ] 调用 `tokenManager.ValidateAccessToken()` - [ ] 检查用户类型(只允许超级管理员、平台用户、代理账号) - [ ] 返回 `UserContextInfo` - [x] 配置 `SkipPaths`(登录、刷新 token 接口) **验证**: - [x] 中间件正确验证 token - [x] 用户类型检查正确 - [x] 公开路由不需要认证 **依赖**: Task 1.1(Token 管理器) --- ### Task 5.2: 配置 H5 认证中间件 **文件**: `internal/bootstrap/middlewares.go` **实现内容**: - [x] 创建 H5 认证中间件(复用 `TokenManager`) - [x] 配置 `TokenValidator` 函数 - [ ] 检查用户类型(只允许代理账号、企业账号) - [x] 配置 `SkipPaths` **验证**: - [x] 用户类型检查正确(与后台不同) - [x] 公开路由不需要认证 **依赖**: Task 5.1(后台中间件) --- ### Task 5.3: 注册后台认证路由 **文件**: `internal/routes/admin.go` **实现内容**: - [x] 创建公开路由组(`/api/admin`) - [ ] POST `/login`:登录 - [ ] POST `/refresh-token`:刷新 token - [x] 创建受保护路由组(`/api/admin`) - [ ] 应用后台认证中间件 - [ ] POST `/logout`:登出 - [ ] GET `/me`:获取当前用户 - [ ] PUT `/password`:修改密码 **验证**: - [x] 路由注册正确 - [x] 受保护路由需要 token - [x] 公开路由无需 token **依赖**: Task 4.1(Handler)、Task 5.1(中间件) --- ### Task 5.4: 注册 H5 认证路由 **文件**: `internal/routes/h5.go`(新建) **实现内容**: - [x] 创建公开路由组(`/api/h5`) - [x] 创建受保护路由组(`/api/h5`) - [x] 注册与后台相同的路由 **验证**: - [x] 路由前缀正确(`/api/h5`) - [x] 中间件正确应用 **依赖**: Task 4.2(Handler)、Task 5.2(中间件) --- ### Task 5.5: 集成到主路由 **文件**: `internal/routes/routes.go` **实现内容**: - [x] 调用 `RegisterAdminAuthRoutes()` - [x] 调用 `RegisterH5AuthRoutes()` **验证**: - [x] 所有路由可访问 - [x] 路由优先级正确 **依赖**: Task 5.3、5.4 --- ## 阶段 6:配置管理 (1 小时) ### Task 6.1: 扩展配置结构 **文件**: `pkg/config/config.go` **实现内容**: - [x] 在 `JWTConfig` 中添加 `AccessTokenTTL` 字段(默认 24 小时) - [x] 在 `JWTConfig` 中添加 `RefreshTokenTTL` 字段(默认 7 天) - [x] 在 `Validate()` 方法中验证 TTL 范围 **验证**: - [x] 配置验证正确 - [x] 默认值合理 **依赖**: 无 --- ### Task 6.2: 更新配置文件 **文件**: `configs/config.yaml`、`configs/config.dev.yaml` **实现内容**: - [x] 添加 `jwt.access_token_ttl` 配置项 - [x] 添加 `jwt.refresh_token_ttl` 配置项 **验证**: - [x] 配置文件语法正确 - [x] 开发环境和生产环境配置合理 **依赖**: Task 6.1 --- ## 阶段 7:测试 (6-8 小时) ### Task 7.1: Token 管理器单元测试 **文件**: `pkg/auth/token_test.go` **测试用例**: - [x] 生成 token 对成功 - [x] 验证有效 access token - [x] 验证有效 refresh token - [x] 验证过期 token 失败 - [x] 验证无效 token 失败 - [x] 刷新 access token 成功 - [x] 撤销 token 成功 - [x] 撤销用户所有 token 成功 - [x] Redis 连接失败处理 **验证**: - [x] 覆盖率 ≥ 90% - [x] 所有测试通过 **依赖**: Task 1.1 --- ### Task 7.2: 认证服务单元测试 **文件**: `internal/service/auth/service_test.go` **测试用例**: - [x] 登录成功(返回 token 和用户信息) - [x] 登录失败(密码错误) - [x] 登录失败(用户名不存在) - [x] 登录失败(账号禁用) - [x] 登出成功(token 失效) - [x] 刷新 token 成功 - [x] 刷新 token 失败(无效 refresh token) - [x] 修改密码成功(旧 token 失效) - [x] 修改密码失败(旧密码错误) **验证**: - [x] 覆盖率 ≥ 90% - [x] Mock `AccountStore` 和 `TokenManager` - [x] 所有测试通过 **依赖**: Task 3.1 --- ### Task 7.3: 后台登录接口集成测试 **文件**: `tests/integration/admin_auth_test.go` **测试用例**: - [x] 后台登录成功(返回 200 和 token) - [x] 后台登录失败(用户名不存在,返回 401) - [x] 后台登录失败(密码错误,返回 401) - [x] 后台登录失败(账号禁用,返回 403) - [x] 登出成功(返回 200) - [x] 刷新 token 成功(返回 200 和新 token) - [x] 获取当前用户信息成功(返回 200 和用户信息) - [x] 修改密码成功(返回 200) **验证**: - [x] 使用真实 PostgreSQL 和 Redis(testcontainers) - [x] 所有测试通过 - [x] 响应格式正确 **依赖**: Task 4.1、5.3 --- ### Task 7.4: H5 登录接口集成测试 **文件**: `tests/integration/h5_auth_test.go` **测试用例**: - [x] H5 登录成功(代理账号) - [x] H5 登录成功(企业账号) - [x] H5 登录失败(平台用户无权访问 H5) - [x] 其他测试用例与后台相同 **验证**: - [x] 用户类型检查正确 - [x] 所有测试通过 **依赖**: Task 4.2、5.4 --- ### Task 7.5: 认证中间件集成测试 **文件**: `tests/integration/auth_middleware_test.go` **测试用例**: - [x] 有效 token 访问受保护路由(返回 200) - [x] 无效 token 返回 401 - [x] 缺失 token 返回 401 - [x] 过期 token 返回 401 - [x] 后台中间件拒绝 H5 用户类型(返回 403) - [x] H5 中间件拒绝平台用户类型(返回 403) - [x] 公开路由无需 token(返回 200) **验证**: - [x] 中间件行为正确 - [x] 错误码和消息正确 **依赖**: Task 5.1、5.2 --- ### Task 7.6: 性能测试 **文件**: `tests/benchmark/auth_bench_test.go` **测试用例**: - [x] Token 验证性能(目标:< 5ms) - [x] 登录性能(目标:< 200ms) - [x] 并发登录测试(1000 并发) **验证**: - [x] 性能达标 - [x] 无内存泄漏 **依赖**: 所有功能完成 --- ## 阶段 8:文档 (2-3 小时) ### Task 8.1: 创建 API 文档 **文件**: `docs/api/auth.md` **内容**: - [x] 登录接口说明(请求、响应、错误码) - [x] 登出接口说明 - [x] Token 刷新接口说明 - [x] 获取当前用户接口说明 - [x] 修改密码接口说明 - [x] 示例 cURL 请求 - [x] 错误码对照表 **验证**: - [x] 文档准确完整 - [x] 示例可执行 **依赖**: 所有功能完成 --- ### Task 8.2: 创建使用指南 **文件**: `docs/auth-usage-guide.md` **内容**: - [x] 如何在新路由中集成认证中间件 - [x] 如何获取当前用户信息 - [x] 如何撤销用户 token - [x] 常见问题(FAQ) - [x] 安全最佳实践 **验证**: - [x] 文档清晰易懂 - [x] 代码示例正确 **依赖**: 所有功能完成 --- ### Task 8.3: 创建架构说明 **文件**: `docs/auth-architecture.md` **内容**: - [x] 认证流程图(Mermaid) - [x] Token 存储结构说明 - [x] 中间件执行顺序 - [x] 安全机制说明 - [x] 设计决策说明 **验证**: - [x] 图表清晰 - [x] 说明准确 **依赖**: 所有功能完成 --- ### Task 8.4: 更新 README **文件**: `README.md` **内容**: - [x] 在"核心功能"章节添加"B 端认证系统" - [x] 在"快速开始"章节添加登录示例 - [x] 更新项目结构说明 **验证**: - [x] 更新准确 - [x] 链接有效 **依赖**: Task 8.1、8.2、8.3 --- ## 阶段 9:验收和发布 (1 小时) ### Task 9.1: 完整性检查 - [x] 所有测试通过(`go test ./...`) - [x] 测试覆盖率达标(`go test -cover ./...`) - [x] LSP 诊断无错误(`lsp_diagnostics`) - [x] 代码格式化(`gofmt`) - [x] 所有 TODO 完成 **验证**: - [x] CI/CD 构建通过 - [x] 无遗留问题 --- ### Task 9.2: 代码审查 - [x] 提交 PR - [x] 代码审查通过 - [x] 修复审查意见 **验证**: - [x] PR 获得批准 --- ### Task 9.3: 部署验证 - [x] 在测试环境部署 - [x] 手动测试所有接口 - [x] 验证性能指标 - [x] 验证安全性 **验证**: - [x] 所有验收标准达成 - [x] 用户满意 --- ## 总结 **总工作量估算**: 22-31 小时(3-5 个工作日) **关键路径**: 1. Task 1.1(Token 管理器)→ Task 3.1(认证服务)→ Task 4.1(Handler)→ Task 5.3(路由) 2. Task 7.1-7.6(测试)必须在功能完成后执行 3. Task 8.1-8.4(文档)可与测试并行 **并行任务**: - Task 1.2、1.3 可与 Task 1.1 并行 - Task 3.2 可与 Task 3.1 并行 - Task 4.2 可在 Task 4.1 完成后立即开始 - Task 5.2、5.4 可在 Task 5.1、5.3 完成后立即开始 - Task 8.1-8.4 可并行执行 **风险点**: - Redis 集成测试可能需要额外调试时间 - 中间件配置可能与现有路由冲突 - 性能测试可能需要优化 --- **任务状态**: 待执行 **创建时间**: 2026-01-15 **最后更新**: 2026-01-15