如何用ChangeNotifierProxyProvider更新变量?API重试401时Header未更新
问题原因及解决方案
核心问题
重试时用的是ApiCalls类里缓存的旧token,而非Auth刚刷新的最新token——因为Auth刷新后触发的Provider更新是异步的,当前onRetry回调里ApiCalls的token还没来得及同步更新。
具体修复步骤
1. 重试时直接从Auth实例取最新token
在ApiCalls的sample方法的onRetry回调里,不要依赖ApiCalls自身的token变量,直接从Auth获取刚刷新后的token:
onRetry: (req, res, retryCount) async { if (retryCount == 0 && res?.statusCode == 401) { final auth = Provider.of<Auth>(context, listen: false); await auth.restoreAccessToken(); // 直接用Auth的最新token更新请求头 req.headers['Authorization'] = auth.token!; print('retry started ${req.headers['Authorization']}'); } },
2. 修复Auth类的token getter逻辑
原来的getter在token过期时仍返回旧token,会导致后续请求带着过期token触发401,改成仅当token有效时才返回:
String? get token { if (accessToken != null && accessTokenExpiryDate != null && accessTokenExpiryDate!.isAfter(DateTime.now())) { return accessToken; } // 过期或不存在时返回null,便于后续判断需要刷新 return null; }
3. 请求初始化时直接从Auth拿token(可选但更可靠)
避免依赖ApiCalls的token缓存,每次发起请求前直接从Auth取最新token:
// 在sample方法里 final auth = Provider.of<Auth>(context, listen: false); var response = http.MultipartRequest("POST", Uri.parse(url)) ..files.add(await http.MultipartFile.fromPath( "imagefile", flutterFunctions.imageFile!.path, contentType: MediaType("image", "jpg"))) ..headers['Authorization'] = auth.token! ..fields.addAll(obj);
额外说明
- 无需从SharedPreferences取token,Auth已持有最新的token数据,直接读取更高效。
- 确保
restoreAccessToken里的notifyListeners()在更新完所有token变量后调用,你当前代码的调用时机是正确的。
内容的提问来源于stack exchange,提问作者Santosh Kumar
相关产品推荐
相关产品推荐

