Files
platforms/docs/项目文档_工作人员端令牌失效恢复_v1.0.md

78 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 工作人员端令牌失效恢复项目文档 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.02026-09-05
- 新增工作人员端统一会话失效异常与请求令牌回调。
- 新增会话清理、设备标识保留、并发幂等和迟到旧请求保护。
- 新增登录失效提示、目标页保存和安全回跳。
- 修复作业检查、个人资料和任务详情全部已知异步 `setState` 错误。
- 新增请求层、会话层、路由、安全地址和作业检查重试测试。
## 5. 维护指南
- 新增受保护接口必须复用已装配 `onUnauthorized` 的统一 `ApiClient`
- 新增文件上传入口不得绕过统一响应解析和会话失效处理。
- 页面捕获 `SessionExpiredException` 时只结束当前交互,不显示普通网络错误,也不重放写操作。
- 替换页面加载任务时,应先创建 `Future`,再用带语句块的同步 `setState` 回调赋值。
- 修改鉴权流程后至少运行 `flutter analyze --no-pub`、完整测试和 Release Web 构建。
## 6. 已知边界
- 本次不新增刷新令牌接口,也不改变服务端 JWT 生命周期和错误码。
- 安全存储删除失败时,下次全新启动可能再次读取旧值,但当前运行会立即退出错误状态并可重新登录。
- 重新登录只恢复页面位置,不恢复或自动执行失效前的打卡、取证、上传及任务操作。