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

如何在Apollo Client中同时实现认证与GraphQL订阅功能?

解决Apollo Client + React Native中GraphQL订阅与认证整合的类型错误及异步token问题

问题根源

你遇到的类型错误是因为混用了旧版apollo-link包和@apollo/client内置的ApolloLink。Apollo Client v3+已将所有链接相关功能整合到@apollo/client中,无需单独安装apollo-link,这会导致类型不兼容。另外,AsyncStorage.getItem是异步方法,同步获取会拿到Promise而非实际token,同时WebSocket连接的认证参数也需要动态获取token。

完整解决方案代码

import { ApolloClient, split, HttpLink, InMemoryCache, ApolloLink, concat } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { createClient } from "graphql-ws";
import AsyncStorage from '@react-native-async-storage/async-storage';

// 1. 配置WebSocket链接,动态获取认证token
const wsLink = new GraphQLWsLink(
  createClient({
    url: "ws://localhost:4000/subscriptions",
    // 异步获取token,支持重连时更新token
    connectionParams: async () => {
      const token = await AsyncStorage.getItem('token');
      return {
        authToken: token ? `Bearer ${token}` : "",
      };
    },
  }),
);

// 2. 配置HTTP链接
const httpLink = new HttpLink({
  uri: 'http://localhost:4000/graphql'
});

// 3. 异步认证中间件(处理HTTP请求的header)
const authLink = new ApolloLink(async (operation, forward) => {
  const token = await AsyncStorage.getItem('token');
  operation.setContext({
    headers: {
      authorization: token ? `Bearer ${token}` : "",
    },
  });
  return forward(operation);
});

// 4. 拼接HTTP链接与认证中间件
const authenticatedHttpLink = concat(authLink, httpLink);

// 5. 拆分链接:订阅用WebSocket,其他用带认证的HTTP
const splitLink = split(
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    );
  },
  wsLink,
  authenticatedHttpLink,
);

// 6. 创建Apollo Client实例
export const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: splitLink,
});

关键修复点说明

  • 统一依赖导入:所有ApolloLink、concat等均从@apollo/client导入,删除对apollo-link包的依赖,彻底解决类型不兼容问题。
  • 异步token处理:
    • HTTP认证中间件使用async/await获取token,ApolloLink支持异步操作,会等待Promise完成后再转发请求。
    • WebSocket的connectionParams配置为异步函数,每次建立连接(包括重连)时都会重新获取最新token,避免token过期后连接失效。
  • 正确的链接拼接顺序:先将认证中间件与HTTP链接拼接,再通过split函数区分订阅和普通请求的链接,确保HTTP请求都携带认证头,订阅请求通过WebSocket传递认证参数。

额外注意事项

  • 确保已安装所有必要依赖:@apollo/client、graphql-ws、@react-native-async-storage/async-storage,无需安装apollo-link。
  • 如果token可能在应用运行中更新(比如用户登录/登出),可以考虑监听token变化,调用wsLink.client.reconnect()触发重新获取token。

内容的提问来源于stack exchange,提问作者pelotador.1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:30:30