5.3 KiB
5.3 KiB
Implementation Plan: Refresh Token 机制
Overview
实现双 Token 认证机制,分为后端改动和前端改动两个阶段。后端先完成数据库、实体、服务和接口的改动,前端再实现自动刷新逻辑。
Tasks
-
1. 后端:数据库和实体层
-
1.1 创建 UserRefreshToken 实体类
- 在
HoneyBox.Model/Entities/目录下创建UserRefreshToken.cs - 包含 Id、UserId、TokenHash、ExpiresAt、CreatedAt、CreatedByIp、RevokedAt、RevokedByIp、ReplacedByToken 字段
- 添加计算属性 IsExpired、IsRevoked、IsActive
- 添加与 User 表的外键关联
- Requirements: 5.1, 5.2
- 在
-
1.2 更新 DbContext 添加 UserRefreshTokens DbSet
- 在
HoneyBoxDbContext.cs中添加DbSet<UserRefreshToken> UserRefreshTokens - 配置表名和索引
- Requirements: 5.1
- 在
-
1.3 创建数据库迁移脚本
- 创建
create_user_refresh_tokens.sql脚本 - 包含表创建、索引和外键约束
- Requirements: 5.1, 5.2
- 创建
-
-
2. 后端:模型和接口层
-
2.1 创建 LoginResponse 模型
- 在
HoneyBox.Model/Models/Auth/目录下创建LoginResponse.cs - 包含 AccessToken、RefreshToken、ExpiresIn 字段
- Requirements: 1.1, 1.2
- 在
-
2.2 创建 RefreshTokenRequest 和 RefreshTokenResult 模型
- 创建请求模型包含 RefreshToken 字段
- 创建结果模型包含 Success、LoginResponse、ErrorMessage 字段
- Requirements: 2.1
-
2.3 扩展 IAuthService 接口
- 添加
RefreshTokenAsync方法 - 添加
RevokeTokenAsync方法 - 添加
RevokeAllUserTokensAsync方法 - Requirements: 2.1, 4.4
- 添加
-
-
[-] 3. 后端:服务层实现
-
3.1 实现 Refresh Token 生成和存储逻辑
- 在 AuthService 中添加
GenerateRefreshToken私有方法 - 使用 SHA256 哈希存储 Token
- 设置 7 天有效期
- Requirements: 1.4, 1.5, 4.1
- 在 AuthService 中添加
-
3.2 修改登录方法返回双 Token
- 修改
WechatMiniProgramLoginAsync返回 LoginResponse - 修改
MobileLoginAsync返回 LoginResponse - 调用 GenerateRefreshToken 生成并存储 Refresh Token
- Requirements: 1.1, 1.2, 1.3, 1.4, 1.5
- 修改
-
3.3 实现 RefreshTokenAsync 方法
- 验证 Refresh Token 有效性(未过期、未撤销)
- 实现 Token 轮换(撤销旧 Token,生成新 Token)
- 记录 ReplacedByToken 关联关系
- Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 5.3
-
3.4 实现 RevokeTokenAsync 方法
- 根据 Token 哈希查找并撤销
- 记录撤销时间和 IP
- Requirements: 4.4
-
* 3.5 编写属性测试:登录响应结构完整性
- Property 1: 登录响应结构完整性
- Validates: Requirements 1.1, 1.2
-
* 3.6 编写属性测试:Token 轮换完整性
- Property 6: Token 轮换完整性
- Validates: Requirements 2.5, 2.6
-
-
4. Checkpoint - 后端服务层完成
- 确保所有测试通过,ask the user if questions arise.
-
5. 后端:控制器层
-
5.1 修改 AuthController 登录接口返回格式
- 修改
WechatMiniProgramLogin返回ApiResponse<LoginResponse> - 修改
MobileLogin返回ApiResponse<LoginResponse> - 保持向后兼容(同时返回 token 字段)
- Requirements: 1.1, 1.2, 6.1
- 修改
-
5.2 新增 Token 刷新接口
- 添加
POST /api/refresh端点 - 接收 RefreshTokenRequest,返回 LoginResponse
- 处理各种错误情况
- Requirements: 2.1, 2.2, 2.3, 2.4
- 添加
-
5.3 新增 Token 撤销接口(可选,用于退出登录)
- 添加
POST /api/logout端点 - 撤销用户的 Refresh Token
- Requirements: 4.4
- 添加
-
-
6. Checkpoint - 后端完成
- 确保所有测试通过,ask the user if questions arise.
- 使用 Postman 或 curl 测试接口
-
7. 前端:Token 存储改造
-
7.1 修改登录成功后的 Token 存储逻辑
- 存储 accessToken 和 refreshToken 到 uni.storage
- 计算并存储 tokenExpireTime
- Requirements: 4.2
-
7.2 修改退出登录清除 Token 逻辑
- 清除 accessToken、refreshToken、tokenExpireTime
- 调用后端撤销接口(可选)
- Requirements: 4.3
-
-
8. 前端:自动刷新机制
-
8.1 实现 refreshToken 方法
- 调用
/api/refresh接口 - 更新本地存储的 Token
- 返回刷新结果
- Requirements: 3.1, 3.2
- 调用
-
8.2 实现请求队列机制
- 添加 isRefreshing 状态标记
- 添加 refreshQueue 请求队列
- 刷新完成后依次执行队列中的请求
- Requirements: 3.5, 3.6
-
8.3 修改 request 方法处理 401 自动刷新
- 检测 401 响应触发刷新
- 刷新成功后重试原请求
- 刷新失败后跳转登录页
- Requirements: 3.1, 3.3, 3.4
-
-
9. Final Checkpoint - 全部完成
- 确保所有测试通过,ask the user if questions arise.
- 端到端测试:登录 → 等待过期 → 自动刷新 → 继续使用
Notes
- Tasks marked with
*are optional and can be skipped for faster MVP - 后端改动需要先执行数据库迁移脚本
- 前端改动需要在后端接口完成后进行
- 建议先在测试环境验证,再部署到生产环境
- Access Token 有效期设置为 30 分钟,可根据需要调整
- Refresh Token 有效期设置为 7 天,可根据需要调整