graphql-ws建立WebSocket连接前如何设置会话Cookie完成鉴权
graphql-ws本身不封装WebSocket握手阶段的请求头逻辑,你使用的ws库原生支持在初始化实例时传入自定义请求头,只需要自定义webSocketImpl的实现,在构造WebSocket实例时注入Cookie头即可。
具体实现
直接替换原有客户端初始化逻辑即可,核心是不要直接传入WebSocket构造函数,而是包一层自定义实例化逻辑,传入ws支持的配置项:
import { createClient } from 'graphql-ws'; import WebSocket from 'ws'; // 预先获取到的有效会话Cookie,格式和浏览器请求头一致,多cookie用分号空格分隔 const COOKIE_STR = 'session_id=your_session_value_here; user_token=your_token_here'; const client = createClient({ url: 'wss://target.io/graphql', webSocketImpl: (url, subProtocols) => { return new WebSocket(url, subProtocols, { headers: { Cookie: COOKIE_STR, // 爬虫场景建议补一个常见浏览器UA,减少被反爬拦截概率 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' }, // 本地调试如果遇到自签名证书报错再开启下面配置,正式场景不建议使用 // rejectUnauthorized: false }); }, on: { connected: (socket) => { console.log("连接已建立,鉴权通过"); // 如果需要同步服务端返回的新Cookie,可以从socket实例上取握手响应头 // const handshakeRes = socket._response; // const updatedCookies = handshakeRes.headers['set-cookie']; }, }, }); (async () => { // 正常编写订阅/查询逻辑即可 let unsubscribe = client.subscribe( { query: `subscription { # 替换成你要调用的订阅字段 targetDataFeed { id content } }` }, { next: (data) => console.log('收到推送数据:', data), error: (err) => console.error('订阅报错:', err), complete: () => console.log('订阅已关闭'), } ); })();
注意事项
- Cookie字符串格式必须和浏览器请求头保持一致,多个Cookie之间用
;分隔,不要写错格式导致鉴权失败 - 如果你需要保持长连接自动重连,建议把Cookie存在变量里,每次重连生成新WebSocket实例时读取最新值,同时在connected回调里同步
set-cookie返回的新值 - 部分站点会校验WebSocket子协议、Origin头,要是还是被拦截,可以在headers里补上
Origin: https://target.io,和浏览器请求对齐
内容的提问来源于stack exchange,提问作者Vizious Developer
相关产品推荐
相关产品推荐

