You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:45:33