Files
platforms/docs/操作日志_用户端令牌失效恢复_20260904.md
2026-09-04 21:54:35 +08:00

53 lines
4.2 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.
# 用户端令牌失效恢复操作日志
操作时间2026-09-04
操作类型:修改、扩展
影响模块:用户端 Flutter App 请求层、会话管理、鉴权路由及错误展示
## 操作前状态
浏览器残留的用户令牌失效后,首页、订单和个人中心的受保护接口返回 401但请求层将其转换为普通网络错误。内存和浏览器安全存储中的令牌仍被视为有效路由因此把 `/login` 再次重定向到 `/home`,用户无法自行恢复登录。
## 具体操作
1. 在统一请求层识别受保护请求的 HTTP 401以及业务码 `1301``1314``1715`,抛出专用会话失效异常。
2. 请求层把实际被拒绝的令牌交给会话层;会话层仅在该令牌仍为当前令牌时执行失效,防止迟到旧请求清除新会话。
3. 会话失效立即清空内存令牌并通知根路由,持久化令牌采用幂等、尽力而为的异步清理;新登录写入前等待旧清理结束。
4. 鉴权守卫通过 `/login?redirect=...&reason=expired` 保存原目标页,并严格限制为站内绝对路径。
5. 登录成功后使用替换导航返回原目标页;目标缺失或非法时回到首页。
6. 注册流程继续携带原目标页;写操作鉴权失败后只返回原页面,不自动重放。
7. 首页、商城、订单、个人中心和通用记录列表忽略专用会话失效异常,避免重复显示网络错误。
## 操作后状态
失效令牌首次被服务端拒绝后,用户会自动进入登录页并看到“登录状态已失效,请重新登录”。重新登录后返回登录前目标页;多个并发 401 只清理和通知一次。普通断网、超时、服务端错误及未鉴权登录接口失败仍按原逻辑展示,不会误清理会话。
## 代码变更
- `apps/user_app/lib/data/services/api_client.dart`+66/-5统一鉴权失败识别、旧令牌回调和专用异常。
- `apps/user_app/lib/app/dependencies.dart`+47/-8幂等会话失效、存储清理及新旧令牌竞态保护。
- `apps/user_app/lib/app/auth_navigation.dart`(新增 33 行):新增站内目标页校验和鉴权地址构造。
- `apps/user_app/lib/app/router.dart`+28/-6保存目标页、失效原因及登录后安全回跳。
- `apps/user_app/lib/ui/features/auth/login_page.dart`+24/-2显示会话失效提示并把目标页传入注册流程。
- `apps/user_app/lib/ui/features/auth/register_page.dart`+26/-2注册完成后保留原登录目标页。
- 首页、个人中心、商城、订单和通用记录列表(合计 +38/-7抑制重复鉴权错误。
- `apps/user_app/test/app/`(新增 205 行)、`apps/user_app/test/data/api_client_test.dart`+97/-2新增会话、路由、安全跳转和请求层回归测试。
- `docs/03-用户端App需求.md``docs/11-数据接口与安全.md`(各新增 2 行):同步功能与安全约束。
## 验证结果
- `flutter analyze --no-pub`:通过,无问题。
- `flutter test --no-pub`:通过,共 27 项测试。
- `flutter build web --release --no-pub --dart-define=API_BASE_URL=http://rest.heqiapp.com`:通过。
- 本地用户端已使用 `API_BASE_URL=http://127.0.0.1:12426` 重新生成 Release Web 构建,并由隐藏运行的 Python 静态服务在 `5180` 提供访问;已停止 Flutter 调试服务,不再依赖 DDC 调试模块和随机 WebSocket。`localhost``127.0.0.1` 均返回 HTTP 200裸根地址可自动跳转并实际渲染带失效提示的登录页。
- 已覆盖 HTTP 401、HTTP 200 鉴权业务码、二进制头像接口、未鉴权接口不清理会话、并发失效、迟到旧请求、存储删除失败、开放重定向防护和登录后回跳。
## 风险评估
- 会话失效依据请求实际携带的令牌比对当前令牌,降低并发和重新登录过程中的竞态风险。
- 持久化删除失败时可能在应用下次完全启动后再次恢复旧令牌,但当前运行会立即退出错误状态;后续受保护请求仍会重新触发清理,不会永久困住用户。
- `redirect` 只允许站内绝对路径并排除鉴权页,避免开放重定向和登录循环。
- 任何产生副作用的业务请求均不自动重放,避免重复支付、下单、退款或工单。