feat: 前端优化
This commit is contained in:
40
openspec/changes/add-auto-refresh-token/proposal.md
Normal file
40
openspec/changes/add-auto-refresh-token/proposal.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# 变更:前端 HTTP 拦截器自动刷新 refreshToken 功能
|
||||
|
||||
## 为什么
|
||||
当前系统的 token 过期处理机制存在缺陷:
|
||||
1. 只在收到 401 错误后才尝试刷新 token
|
||||
2. 导致用户看到错误提示后才发现 token 已过期
|
||||
3. 影响用户体验,特别是长时间操作时
|
||||
|
||||
需要实现在请求前主动检查并刷新即将过期的 token,提升用户体验。
|
||||
|
||||
## 什么发生变化
|
||||
在 `frontend/api/axios/client.js` 的请求拦截器中添加智能 token 刷新机制:
|
||||
|
||||
### 新增功能
|
||||
1. **预检查机制**:在每次需要认证的请求前,检查 token 是否即将过期(默认 5 分钟缓冲时间)
|
||||
2. **自动刷新**:如果 token 即将过期,自动使用 refreshToken 获取新 token
|
||||
3. **并发控制**:防止多个请求同时触发 token 刷新
|
||||
4. **无缝体验**:用户无需感知 token 刷新过程,请求正常进行
|
||||
|
||||
### 影响的文件
|
||||
- `frontend/api/axios/client.js` - 核心拦截器逻辑
|
||||
- `frontend/api/http.js` - 可能需要更新调用方式
|
||||
- `frontend/utils/token-manager.js` - 使用现有的 `isExpired()` 方法
|
||||
|
||||
### 关键设计决策
|
||||
1. **缓冲时间**:使用 5 分钟作为 token 刷新缓冲时间(可配置)
|
||||
2. **白名单**:刷新 token 接口 `/auth/refresh-token` 不需要 token,直接跳过检查
|
||||
3. **错误处理**:刷新失败时清理 token 并跳转登录页
|
||||
4. **状态管理**:使用 Promise 锁机制防止并发刷新
|
||||
|
||||
## 影响
|
||||
- **用户体验**:显著提升 - 消除因 token 过期导致的请求失败
|
||||
- **系统稳定性**:提高 - 减少 401 错误发生频率
|
||||
- **安全性**:保持 - 继续使用 refreshToken 机制,安全性不变
|
||||
- **性能影响**:极小 - 仅在 token 即将过期时触发一次刷新请求
|
||||
|
||||
## 兼容性
|
||||
- 向后兼容:不影响现有认证流程
|
||||
- API 兼容:不改变后端接口契约
|
||||
- 配置兼容:可配置缓冲时间,默认 5 分钟
|
||||
74
openspec/changes/add-auto-refresh-token/specs/auth/spec.md
Normal file
74
openspec/changes/add-auto-refresh-token/specs/auth/spec.md
Normal file
@@ -0,0 +1,74 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 请求前自动检查并刷新 token
|
||||
系统 MUST 在发送需要认证的 HTTP 请求前,主动检查访问令牌是否即将过期,如果即将过期则自动使用 refreshToken 刷新,避免因 token 过期导致请求失败。
|
||||
|
||||
#### Scenario: Token 即将过期时自动刷新
|
||||
- **GIVEN** 用户已登录且 accessToken 将在 3 分钟后过期
|
||||
- **WHEN** 发起需要认证的 API 请求
|
||||
- **THEN** 系统自动使用 refreshToken 调用刷新接口
|
||||
- **AND** 刷新成功后使用新的 accessToken 发送原请求
|
||||
- **AND** 用户无感知,请求正常完成
|
||||
|
||||
#### Scenario: Token 正常情况下不触发刷新
|
||||
- **GIVEN** 用户已登录且 accessToken 将在 30 分钟后过期
|
||||
- **WHEN** 发起需要认证的 API 请求
|
||||
- **THEN** 系统检查 token 未过期
|
||||
- **AND** 直接使用当前 token 发送请求
|
||||
- **AND** 不调用刷新接口
|
||||
|
||||
#### Scenario: 白名单接口跳过 token 检查
|
||||
- **GIVEN** 用户已登录
|
||||
- **WHEN** 访问以下接口:
|
||||
- `/auth/login`(登录)
|
||||
- `/auth/refresh-token`(刷新 token)
|
||||
- `/auth/register`(注册)
|
||||
- `/auth/send-sms-code`(发送短信)
|
||||
- **THEN** 系统跳过 token 过期检查
|
||||
- **AND** 不添加 Authorization 头
|
||||
|
||||
#### Scenario: 防止并发刷新 token
|
||||
- **GIVEN** 用户已登录且 token 即将过期
|
||||
- **WHEN** 同时发起 3 个需要认证的请求
|
||||
- **THEN** 只有一个请求触发 token 刷新
|
||||
- **AND** 其他 2 个请求等待刷新完成后使用新 token
|
||||
- **AND** 刷新接口只被调用一次
|
||||
|
||||
#### Scenario: 刷新失败时清理状态
|
||||
- **GIVEN** 用户已登录且 token 已过期
|
||||
- **WHEN** 发起需要认证的请求
|
||||
- **AND** 调用 refreshToken 接口返回 401(refreshToken 也无效)
|
||||
- **THEN** 系统自动清理 localStorage 中的所有 token
|
||||
- **AND** 跳转到登录页要求用户重新登录
|
||||
- **AND** 拒绝所有后续请求直到重新登录
|
||||
|
||||
#### Scenario: 自定义缓冲时间
|
||||
- **GIVEN** 系统配置 token 刷新缓冲时间为 10 分钟
|
||||
- **WHEN** accessToken 将在 12 分钟后过期
|
||||
- **THEN** 系统认为 token 仍然有效
|
||||
- **WHEN** accessToken 将在 8 分钟后过期
|
||||
- **THEN** 系统自动触发 token 刷新
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 请求拦截器增强
|
||||
现有的请求拦截器 MUST 增强为支持 token 预检查和自动刷新功能。
|
||||
|
||||
#### Scenario: 拦截器新增预检查逻辑
|
||||
- **GIVEN** 用户已登录且系统配置了自动刷新功能
|
||||
- **WHEN** 发起需要认证的 HTTP 请求
|
||||
- **THEN** 拦截器在添加 Authorization 头之前检查 token 过期时间
|
||||
- **AND** 如果 token 即将过期,启动异步刷新流程
|
||||
- **AND** 刷新完成后使用新 token 添加到请求头
|
||||
- **AND** 继续发送原始请求
|
||||
|
||||
**Modified Behavior**:
|
||||
- 在添加 Authorization 头之前,先检查 token 是否即将过期
|
||||
- 如果即将过期且不在刷新过程中,则启动异步刷新流程
|
||||
- 刷新完成后继续添加 Authorization 头并发送请求
|
||||
- 使用 Promise 机制确保所有等待刷新的请求按顺序执行
|
||||
|
||||
**Backward Compatibility**:
|
||||
- 现有的 401 错误处理机制保持不变
|
||||
- 如果预检查失败(如 refreshToken 无效),仍然会触发 401 处理
|
||||
- 所有现有接口调用方式保持不变
|
||||
33
openspec/changes/add-auto-refresh-token/tasks.md
Normal file
33
openspec/changes/add-auto-refresh-token/tasks.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# 任务清单:自动刷新 refreshToken 功能
|
||||
|
||||
## 1. 实现请求拦截器 token 预检查
|
||||
- [ ] 1.1 在 `client.js` 请求拦截器中添加 token 过期检查逻辑
|
||||
- [ ] 1.2 调用 `tokenManager.isExpired()` 检查是否需要刷新
|
||||
- [ ] 1.3 对白名单接口跳过检查(login、refresh-token、register 等)
|
||||
|
||||
## 2. 实现自动刷新机制
|
||||
- [ ] 2.1 创建异步刷新函数,内部调用 `/auth/refresh-token` 接口
|
||||
- [ ] 2.2 刷新成功后更新 localStorage 中的 token
|
||||
- [ ] 2.3 刷新失败时清理 token 并抛出错误
|
||||
|
||||
## 3. 实现并发控制
|
||||
- [ ] 3.1 添加 `isRefreshing` 标志位防止并发刷新
|
||||
- [ ] 3.2 如果正在刷新,等待刷新完成
|
||||
- [ ] 3.3 使用 Promise 链确保请求顺序执行
|
||||
|
||||
## 4. 优化用户体验
|
||||
- [ ] 4.1 添加调试日志(仅开发环境)
|
||||
- [ ] 4.2 确保刷新过程对用户透明
|
||||
- [ ] 4.3 错误处理时提供清晰的日志信息
|
||||
|
||||
## 5. 测试验证
|
||||
- [ ] 5.1 模拟 token 过期场景,验证自动刷新
|
||||
- [ ] 5.2 验证并发请求不会触发多次刷新
|
||||
- [ ] 5.3 验证白名单接口不受影响
|
||||
- [ ] 5.4 验证刷新失败时的错误处理
|
||||
|
||||
## 6. 代码审查
|
||||
- [ ] 6.1 检查代码规范
|
||||
- [ ] 6.2 验证日志输出适当
|
||||
- [ ] 6.3 确认性能影响最小
|
||||
- [ ] 6.4 更新相关注释
|
||||
Reference in New Issue
Block a user