Apollo对接Hasura实现GraphQL订阅时JWT模式缺少Authorization header问题
React + Hasura 订阅功能授权报错解决方案
错误根因
报错本质是WebSocket链路的授权参数未正确传递到Hasura,你的代码存在两处核心问题:
setContext仅适配HTTP类型的Apollo链路,无法作用于WebSocketLink的连接初始化逻辑,你编写的wsAuthLink没有实际生效,WS连接发起初始化时未携带token- Hasura的WebSocket连接
connection_init消息不需要嵌套headers层级,直接在connectionParams根层级传递Authorization字段即可
修正后的实现代码
替换你原有WebSocket链路及Apollo客户端初始化部分的代码即可:
/* Graphql Start */ const { isLoading, error, getAccessTokenSilently } = useAuth0(); /* HTTP Link Start */ const authLink = setContext(async () => { const token = await getAccessTokenSilently(); return { headers: { Authorization: `Bearer ${token}` } }; }); const httpLink = createHttpLink({ uri: 'https://####.hasura.app/v1/graphql', }); const newHttpLink = authLink.concat(httpLink); /* HTTP Link End */ /* Websocket Start */ // 移除无用的wsAuthLink,直接在WebSocketLink配置中动态获取token const wsLink = new WebSocketLink({ uri: 'wss://####.hasura.app/v1/graphql', options: { reconnect: true, timeout: 30000, // connectionParams支持异步函数,动态获取最新token connectionParams: async () => { const token = await getAccessTokenSilently(); return { Authorization: `Bearer ${token}` }; } } }); /* Websocket End */ const splitLink = split( ({ query }) => { const definition = getMainDefinition(query); return ( definition.kind === 'OperationDefinition' && definition.operation === 'subscription' ); }, wsLink, newHttpLink, ); const client = new ApolloClient({ link: splitLink, cache: new InMemoryCache(), connectToDevTools: true }); /* Graphql End */
验证方式
修改后可通过浏览器开发者工具验证参数是否生效:
- 打开「网络」面板,筛选
WS类型的请求 - 找到对应Hasura域名的WebSocket连接,点击进入「帧/Frames」标签
- 找到类型为
connection_init的消息,确认消息体中已携带正确的Authorization字段
内容的提问来源于stack exchange,提问作者Blake Hayes
相关产品推荐
相关产品推荐

