如何在Chrome扩展background脚本的WebSocket连接中携带Cookie
问题原因
- Chrome扩展的background脚本运行在独立的扩展origin下,和
localhost:8000属于跨源场景 fetch请求可以正常携带Cookie,是因为你显式配置了credentials: 'include',允许跨源请求携带第三方Cookie- 原生
WebSocket构造函数没有提供credentials相关的配置参数,跨源场景下默认不会携带目标域名的Cookie,这是浏览器API的设计限制,和你配置的manifest权限无关
可行解决方案
方案1:通过查询参数传递鉴权信息
先通过chrome.cookiesAPI读取localhost域名下的会话Cookie,将Cookie值作为查询参数拼接在WebSocket连接地址中,后端从查询参数取值完成鉴权。
- 首先在manifest.json的
permissions数组中新增cookies权限:
"permissions": [ // 原有权限保留 "cookies" ]
- 调整WebSocket创建逻辑:
chrome.cookies.get({ url: 'http://localhost:8000', name: '你的会话Cookie名称(如session_id)' }, (cookie) => { if (!cookie) return console.error('未找到会话Cookie'); // 将Cookie值拼接到连接地址的查询参数中 const ws = new WebSocket(`ws://localhost:8000/?session_token=${cookie.value}`); })
- 后端修改鉴权逻辑,优先从查询参数中读取
session_token完成身份校验。
方案2:通过WebSocket子协议头传递鉴权信息
相比查询参数,该方式不会把鉴权信息暴露在服务端的访问日志中,安全性更高。
- 同样先拿到会话token(可以通过
chrome.cookies读取,也可以先调用一次带credentials: 'include'的接口获取临时token) - 创建WebSocket时把子协议参数传入:
// 第二个参数为子协议数组,第二项填你的实际token值 const ws = new WebSocket('ws://localhost:8000/', ['authorization', '你的会话token']);
- 后端读取请求头的
Sec-WebSocket-Protocol字段,取第二个值作为token校验,校验通过后返回响应时也要携带相同的Sec-WebSocket-Protocol头即可完成握手。
内容的提问来源于stack exchange,提问作者hldev
相关产品推荐
相关产品推荐

