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

Flutter中GraphQL动态添加Authorization Token问题求助

动态更新GraphQL请求的Authorization Token解决方案

你的核心问题是GraphQL客户端初始化时Token还未获取,导致请求无法携带有效Token。以下是几种可行的解决方式:

方案一:使用AuthLink(推荐)

利用graphql_flutter提供的AuthLink,它会在每次请求发起前动态获取最新Token,完美适配Token后续获取的场景:

void main() async{
  WidgetsFlutterBinding.ensureInitialized();
  final _sessionDataProvider = SessionDataProvider();

  // 初始化基础HttpLink,不预设Authorization头
  final httpLink = HttpLink("https://my_api.ru/graphql/");

  // 创建AuthLink,每次请求时自动拉取最新Token
  final authLink = AuthLink(
    getToken: () async {
      String? token = await _sessionDataProvider.getSessionId();
      return token != null ? "Bearer $token" : null;
    },
  );

  // 拼接AuthLink和HttpLink,让请求先经过Token校验再发往服务器
  final link = authLink.concat(httpLink);

  ValueNotifier<GraphQLClient> client = ValueNotifier(GraphQLClient(
    link: link,
    cache: GraphQLCache(store: InMemoryStore()),
  ));

  var app = GraphQLProvider(client: client, child: MyApp());
  runApp(app);
}

原理

AuthLink作为请求链路的前置环节,每次发起GraphQL请求时都会调用getToken方法获取最新的Token值,再将其注入请求头中。不管Token是初始化后多久获取到的,请求时都会带上当前最新的有效Token。

方案二:主动更新GraphQLClient

如果需要在Token更新(比如登录成功、刷新Token)后立刻让后续请求使用新Token,可以通过更新ValueNotifier中的GraphQLClient实现:

  1. 初始化时先创建不带Token的客户端:
void main() async{
  WidgetsFlutterBinding.ensureInitialized();
  final _sessionDataProvider = SessionDataProvider();

  // 初始化无Token的HttpLink
  final httpLink = HttpLink("https://my_api.ru/graphql/");
  ValueNotifier<GraphQLClient> client = ValueNotifier(GraphQLClient(
    link: httpLink,
    cache: GraphQLCache(store: InMemoryStore()),
  ));

  var app = GraphQLProvider(client: client, child: MyApp());
  runApp(app);
}
  1. 在获取到Token后(比如登录成功回调中)更新客户端:
// 假设登录成功后拿到了新token
void updateClientWithNewToken(String newToken) {
  final newHttpLink = HttpLink(
    "https://my_api.ru/graphql/",
    defaultHeaders: {"Authorization": "Bearer $newToken"}
  );
  // 更新ValueNotifier的值,所有依赖该客户端的组件会自动使用新配置
  client.value = GraphQLClient(
    link: newHttpLink,
    cache: GraphQLCache(store: InMemoryStore()),
  );
}

如果需要更灵活的Token处理逻辑(比如添加Token过期判断),可以自定义一个Link来注入请求头:

class AuthHeaderLink extends Link {
  final SessionDataProvider sessionDataProvider;

  AuthHeaderLink(this.sessionDataProvider);

  @override
  Stream<Response> request(Request request, [NextLink? forward]) async* {
    String? token = await sessionDataProvider.getSessionId();
    if (token != null) {
      // 将最新Token注入请求头
      request = request.updateContextEntry<HttpLinkHeaders>(
        (headers) => HttpLinkHeaders(
          headers: {
            ...headers?.headers ?? {},
            'Authorization': 'Bearer $token',
          },
        ),
      );
    }
    // 传递请求到下一个链路环节
    yield* forward!(request);
  }
}

初始化时拼接使用:

void main() async{
  WidgetsFlutterBinding.ensureInitialized();
  final _sessionDataProvider = SessionDataProvider();

  final httpLink = HttpLink("https://my_api.ru/graphql/");
  final authHeaderLink = AuthHeaderLink(_sessionDataProvider);
  final link = authHeaderLink.concat(httpLink);

  ValueNotifier<GraphQLClient> client = ValueNotifier(GraphQLClient(
    link: link,
    cache: GraphQLCache(store: InMemoryStore()),
  ));

  var app = GraphQLProvider(client: client, child: MyApp());
  runApp(app);
}

内容的提问来源于stack exchange,提问作者Happy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:55:19