Flutter中同步请求触发401时重复刷新Token的问题及解决方案咨询
Flutter中同步请求触发401时重复刷新Token的问题及解决方案咨询
嘿,我太懂你这个困扰了!用Future.wait同时发起多个请求,结果每个请求都碰上个401,刷新Token的代码被反复调用N次——不仅白白消耗资源,搞不好还会因为多次刷新导致Token状态混乱,真的很闹心。
首先得明确:完全没必要把所有请求改成同步,核心问题是现在每个401请求都会独立触发刷新Token的逻辑,它们互相不知道对方正在刷新,才会重复执行。我们只需要给刷新Token的操作加个“全局锁”,让同一时间只有一次刷新在进行,其他请求等着拿结果就行。
这里给你一个具体的实现方案,用Completer来控制刷新操作的唯一性:
class AppAuthenticator extends Authenticator { // 全局Completer,用来标记当前是否有刷新Token的操作在进行 Completer<String?>? _refreshLock; @override FutureOr<Request?> authenticate(Request request, Response response, [Request? originalRequest]) async { if (response.statusCode == 401) { // 如果已经有刷新请求在跑,直接等它完成,拿现成的新Token if (_refreshLock != null) { final newToken = await _refreshLock!.future; if (newToken != null) { // 用新Token重新构造请求并返回 return request.copyWith( headers: {...request.headers, 'Authorization': 'Bearer $newToken'} ); } return null; } // 没有刷新操作在进行,初始化锁 _refreshLock = Completer(); try { // 执行你的Token刷新逻辑 final newToken = await _restApi.refreshToken(); // 刷新成功,把结果传给所有等待的请求 _refreshLock!.complete(newToken); if (newToken != null) { // 返回用新Token重新组装的请求 return request.copyWith( headers: {...request.headers, 'Authorization': 'Bearer $newToken'} ); } } catch (error) { // 刷新失败,通知所有等待的请求 _refreshLock!.completeError(error); // 这里可以加刷新失败后的处理,比如跳转到登录页 } finally { // 不管成功失败,都要释放锁,让后续的请求能正常触发刷新 _refreshLock = null; } } return null; } }
简单说下这个方案的逻辑:
- 当第一个401请求进来时,初始化
_refreshLock,开始执行刷新Token的操作 - 后面的401请求进来时,发现
_refreshLock已经存在,就直接等待这个Completer的结果,不会重复发起刷新 - 刷新完成后,所有等待的请求都会拿到同一个新Token,然后各自重新发起请求
- 最后不管刷新成功还是失败,都会清空
_refreshLock,保证后续的401请求能正常触发新的刷新
这样既保留了Future.wait的并发请求优势,又解决了重复刷新Token的问题,完美~
备注:内容来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

