diff --git a/app/lib/app.dart b/app/lib/app.dart index 5c47d6c..1d89a02 100644 --- a/app/lib/app.dart +++ b/app/lib/app.dart @@ -72,6 +72,11 @@ class NuanjiApp extends StatelessWidget { } }); + // Token 刷新彻底失败时 → 派发 AuthExpired → 路由重定向到登录页 + apiClient.onAuthFailed = () { + authBloc.add(const AuthExpired()); + }; + return MultiRepositoryProvider( providers: [ RepositoryProvider.value(value: apiClient), diff --git a/app/lib/data/remote/api_client.dart b/app/lib/data/remote/api_client.dart index 45f64bc..a7d5f9d 100644 --- a/app/lib/data/remote/api_client.dart +++ b/app/lib/data/remote/api_client.dart @@ -35,6 +35,12 @@ class ApiClient { /// 使用回调模式避免 ApiClient ↔ AuthRepository 循环依赖。 Future Function()? onRefreshToken; + /// 认证彻底失败回调 — 刷新 token 失败后由 app.dart 注册 + /// + /// 通知 AuthBloc 派发 AuthExpired 事件,触发路由重定向到登录页。 + /// 解决审计 9a-AUTH-01:刷新失败时用户不会被留在死页面。 + void Function()? onAuthFailed; + /// 是否正在刷新 token(防止并发 401 触发多次刷新) bool _isRefreshing = false; @@ -95,8 +101,9 @@ class ApiClient { _isRefreshing = false; } - // 刷新失败或无刷新回调 → 清除 token + // 刷新失败或无刷新回调 → 清除 token,通知全局认证失效 _token = null; + onAuthFailed?.call(); } handler.next(error); },