fix(app): Token 刷新彻底失败时通知 AuthBloc 派发 AuthExpired
审计 9a-AUTH-01 修复: - ApiClient 新增 onAuthFailed 回调,在 401 刷新失败后触发 - app.dart 注册回调:派发 AuthExpired → GoRouter 重定向到登录页 - 之前刷新失败只清除内存 token,用户停留在死页面 - 现在 401 → 尝试刷新 → 失败 → AuthExpired → 自动跳转登录
This commit is contained in:
@@ -72,6 +72,11 @@ class NuanjiApp extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Token 刷新彻底失败时 → 派发 AuthExpired → 路由重定向到登录页
|
||||||
|
apiClient.onAuthFailed = () {
|
||||||
|
authBloc.add(const AuthExpired());
|
||||||
|
};
|
||||||
|
|
||||||
return MultiRepositoryProvider(
|
return MultiRepositoryProvider(
|
||||||
providers: [
|
providers: [
|
||||||
RepositoryProvider<ApiClient>.value(value: apiClient),
|
RepositoryProvider<ApiClient>.value(value: apiClient),
|
||||||
|
|||||||
@@ -35,6 +35,12 @@ class ApiClient {
|
|||||||
/// 使用回调模式避免 ApiClient ↔ AuthRepository 循环依赖。
|
/// 使用回调模式避免 ApiClient ↔ AuthRepository 循环依赖。
|
||||||
Future<String?> Function()? onRefreshToken;
|
Future<String?> Function()? onRefreshToken;
|
||||||
|
|
||||||
|
/// 认证彻底失败回调 — 刷新 token 失败后由 app.dart 注册
|
||||||
|
///
|
||||||
|
/// 通知 AuthBloc 派发 AuthExpired 事件,触发路由重定向到登录页。
|
||||||
|
/// 解决审计 9a-AUTH-01:刷新失败时用户不会被留在死页面。
|
||||||
|
void Function()? onAuthFailed;
|
||||||
|
|
||||||
/// 是否正在刷新 token(防止并发 401 触发多次刷新)
|
/// 是否正在刷新 token(防止并发 401 触发多次刷新)
|
||||||
bool _isRefreshing = false;
|
bool _isRefreshing = false;
|
||||||
|
|
||||||
@@ -95,8 +101,9 @@ class ApiClient {
|
|||||||
_isRefreshing = false;
|
_isRefreshing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 刷新失败或无刷新回调 → 清除 token
|
// 刷新失败或无刷新回调 → 清除 token,通知全局认证失效
|
||||||
_token = null;
|
_token = null;
|
||||||
|
onAuthFailed?.call();
|
||||||
}
|
}
|
||||||
handler.next(error);
|
handler.next(error);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user