78 lines
4.4 KiB
Markdown
78 lines
4.4 KiB
Markdown
# 工作人员端令牌失效恢复项目文档 v1.0
|
||
|
||
## 1. 项目概述
|
||
|
||
- 项目名称:工作人员端令牌失效恢复与异步刷新修复。
|
||
- 主要功能:受保护接口拒绝失效令牌后自动清理会话、返回登录页并安全保存原目标页;同时消除页面刷新时向 `setState` 返回异步任务的错误写法。
|
||
- 技术栈:Flutter、Dart、GoRouter、HTTP、Flutter Secure Storage、Flutter Widget Test。
|
||
- 运行环境:项目当前 Flutter SDK、Web Release 静态服务及本地平台 API。
|
||
- 实施范围:仅 `service_app` 请求层、会话层、路由和页面错误处理;后端接口与数据库不变。
|
||
|
||
## 2. 目录结构说明
|
||
|
||
```text
|
||
platforms/
|
||
├── apps/service_app/
|
||
│ ├── lib/
|
||
│ │ ├── app/
|
||
│ │ │ ├── auth_navigation.dart # 登录地址与站内回跳校验
|
||
│ │ │ ├── dependencies.dart # 会话失效、清理和并发保护
|
||
│ │ │ └── router.dart # 鉴权守卫、过期提示和安全回跳
|
||
│ │ ├── data/services/
|
||
│ │ │ ├── api_client.dart # HTTP 与业务码鉴权失效识别
|
||
│ │ │ └── secure_session_store.dart # 可测试的安全存储接口
|
||
│ │ └── ui/features/ # 页面错误抑制和同步刷新
|
||
│ └── test/
|
||
│ ├── app/ # 会话、回跳和路由测试
|
||
│ ├── data/api_client_test.dart # 请求层鉴权测试
|
||
│ └── ui/preflight_page_test.dart # 作业检查重试组件测试
|
||
└── docs/ # 需求、安全、项目和操作日志
|
||
```
|
||
|
||
## 3. 核心文件说明
|
||
|
||
### 请求与上传
|
||
|
||
- `ApiClient` 在请求发出前保存实际令牌快照。
|
||
- 受保护请求返回 HTTP 401,或统一响应返回业务码 `1301—1314`、`1715` 时,通知会话层并抛出 `SessionExpiredException`。
|
||
- 匿名登录请求不触发已有会话清理;普通 JSON 请求和文件上传使用同一识别规则。
|
||
|
||
### 会话与安全存储
|
||
|
||
- `StaffSession.invalidate` 只接受与当前令牌一致的被拒令牌,并通过失效标记保证幂等。
|
||
- 失效时立即清空内存中的令牌、工作人员标识和角色,保留设备标识并通知路由。
|
||
- 持久化删除逐项尽力执行;单项失败只记录调试信息,不阻塞返回登录页。
|
||
- 新登录写入前等待旧清理任务结束,避免迟到删除覆盖新会话。
|
||
|
||
### 路由与页面
|
||
|
||
- 鉴权守卫把原目标页保存为登录页 `redirect` 参数,并通过 `reason=expired` 展示失效原因。
|
||
- 仅允许站内绝对路径回跳;拒绝外部地址、协议相对地址、反斜杠地址和登录页循环。
|
||
- 登录成功后返回原目标页,缺失或非法目标默认进入 `/preflight`。
|
||
- 页面层不重复展示鉴权错误;普通断网和服务端错误仍沿用既有提示。
|
||
- 作业检查、个人资料和任务详情中的 7 处异步刷新均改为同步 `setState` 赋值。
|
||
|
||
## 4. 变更记录
|
||
|
||
### v1.0(2026-09-05)
|
||
|
||
- 新增工作人员端统一会话失效异常与请求令牌回调。
|
||
- 新增会话清理、设备标识保留、并发幂等和迟到旧请求保护。
|
||
- 新增登录失效提示、目标页保存和安全回跳。
|
||
- 修复作业检查、个人资料和任务详情全部已知异步 `setState` 错误。
|
||
- 新增请求层、会话层、路由、安全地址和作业检查重试测试。
|
||
|
||
## 5. 维护指南
|
||
|
||
- 新增受保护接口必须复用已装配 `onUnauthorized` 的统一 `ApiClient`。
|
||
- 新增文件上传入口不得绕过统一响应解析和会话失效处理。
|
||
- 页面捕获 `SessionExpiredException` 时只结束当前交互,不显示普通网络错误,也不重放写操作。
|
||
- 替换页面加载任务时,应先创建 `Future`,再用带语句块的同步 `setState` 回调赋值。
|
||
- 修改鉴权流程后至少运行 `flutter analyze --no-pub`、完整测试和 Release Web 构建。
|
||
|
||
## 6. 已知边界
|
||
|
||
- 本次不新增刷新令牌接口,也不改变服务端 JWT 生命周期和错误码。
|
||
- 安全存储删除失败时,下次全新启动可能再次读取旧值,但当前运行会立即退出错误状态并可重新登录。
|
||
- 重新登录只恢复页面位置,不恢复或自动执行失效前的打卡、取证、上传及任务操作。
|