53 lines
4.2 KiB
Markdown
53 lines
4.2 KiB
Markdown
# 用户端令牌失效恢复操作日志
|
||
|
||
操作时间: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` 只允许站内绝对路径并排除鉴权页,避免开放重定向和登录循环。
|
||
- 任何产生副作用的业务请求均不自动重放,避免重复支付、下单、退款或工单。
|