# 工作人员端令牌失效恢复操作日志 操作时间:2026-09-05 19:44:58 操作类型:修改、扩展 影响模块:工作人员端请求层、会话管理、鉴权路由、登录页、业务页面刷新及本地 Web 运行方式 ## 操作前状态 浏览器保留工作人员登录状态,但令牌已被后端拒绝。作业前检查接口实际返回 HTTP 401,客户端却将其显示为“请检查网络”,并因路由继续把本地令牌视为有效而无法返回登录页。点击“重新加载”还会将异步任务从 `setState` 回调返回,在 Flutter 调试模式触发断言;相同写法在作业检查、个人资料和任务详情中共有 7 处。 ## 具体操作 1. 请求层保存每个请求实际使用的令牌,统一识别受保护请求的 HTTP 401 与业务码 `1301—1314`、`1715`。 2. 普通 JSON 请求和文件上传均通知会话层并抛出专用失效异常;匿名登录请求不触发清理。 3. 会话层仅处理与当前令牌一致的拒绝通知,幂等清除令牌、工作人员标识和角色,并保留设备标识。 4. 持久化字段逐项尽力删除;新登录写入前等待旧清理任务结束,避免迟到旧请求和删除任务破坏新会话。 5. 路由将失效前的站内目标页写入登录地址,并通过 `reason=expired` 展示明确提示;重新登录后安全回跳。 6. 页面层忽略专用会话失效异常,不再重复显示普通网络错误,也不自动重放写操作。 7. 将全部 7 处异步 `setState` 赋值改为同步状态回调,并新增统一页面刷新方法。 8. 新增请求层、会话层、路由、安全回跳和作业检查重试测试,同步需求、安全和项目文档。 9. 构建连接本地后端 `12426` 的 Release Web 产物,将 `5181` 从 Flutter 调试服务切换为隐藏的静态服务。 ## 操作后状态 工作人员端遇到失效令牌后会立即停止当前页面错误展示,清理会话并进入登录页,显示“登录状态已失效,请重新登录”。登录地址保留合法原目标页,重新登录后可返回;非法或缺失目标默认进入作业前检查。写操作不会自动重放,设备标识不会因会话失效丢失。所有已知页面刷新入口不再向 `setState` 返回 `Future`。 ## 代码变更 - `apps/service_app/lib/data/services/api_client.dart`(+58/-15):统一鉴权失效识别、令牌快照、专用异常和上传处理。 - `apps/service_app/lib/app/dependencies.dart`(+57/-15):会话清理、设备保留、幂等及竞态保护。 - `apps/service_app/lib/data/services/secure_session_store.dart`(+18/-1):新增可测试的会话存储接口。 - `apps/service_app/lib/app/auth_navigation.dart`(新增 32 行):登录地址构造和站内目标校验。 - `apps/service_app/lib/app/router.dart`(+21/-5)、登录页(+15/-2):失效跳转、提示和登录后回跳。 - 作业检查、个人资料、任务详情、任务列表与取证页面(合计 +65/-8):鉴权错误抑制与同步刷新。 - `apps/service_app/test/app/`、`test/data/api_client_test.dart`、`test/ui/preflight_page_test.dart`(新增 448 行):鉴权、并发、回跳和重试回归测试。 - `docs/04-服务端App需求.md`、`docs/11-数据接口与安全.md`:同步功能和安全约束。 - `docs/项目文档_工作人员端令牌失效恢复_v1.0.md`(新增 77 行):记录结构、行为、维护方法和边界。 ## 验证结果 - `flutter analyze --no-pub`:通过,无问题。 - `flutter test --no-pub`:通过,共 20 项测试。 - 作业检查组件测试实际执行首次失败和点击重试,确认页面恢复且无 Flutter 断言。 - `flutter build web --release --no-pub --dart-define=API_BASE_URL=http://127.0.0.1:12426`:通过。 - 本地 `5181` 已由 Python Release 静态服务监听并返回 HTTP 200;`12426` 后端健康检查返回 HTTP 200。 - 浏览器端到端验证:原 `/preflight` 页面携带残留失效令牌刷新后,实际跳转至 `/login?redirect=/preflight&reason=expired`,并显示“登录状态已失效,请重新登录”。 ## 风险评估 - 会话失效按请求令牌快照与当前令牌比对,避免并发请求或重新登录期间的旧响应清除新会话。 - 持久化删除失败时,当前运行仍可立即恢复登录;下次全新启动可能再次读取旧值并重新触发清理。 - 回跳只接受站内绝对路径并排除登录页,降低开放重定向和登录循环风险。 - 打卡、取证、上传和任务状态操作不自动重放,避免重复副作用。 - 后端接口、JWT 生命周期、数据库和普通错误文案均未修改。