如何使Chrome通过WebSocket握手请求发送Cookie?

时间:2019-03-26 22:39:56

标签: google-chrome cookies websocket

我需要发送一个带有websocket握手请求的cookie,以确保负载均衡器将请求路由到特定的后端。在Firefox,Safari和websocket-sharp中可以正常使用,但是我无法让Chrome发送带有websocket握手请求的cookie。

我在负载均衡器(Traefik)中启用了粘性会话,并使用现有的SockJS代码在Firefox和Safari上“正常工作”。

第一个请求没有cookie,并且负载均衡器在握手响应(101个交换协议)上设置一个。随后的Websocket握手请求将发送cookie,并且所建立的Websocket连接将建立到正确的后端。

在我的websocket-sharp客户端中,我在打开连接之前显式设置了cookie,它可以按预期工作。

Chrome永远不会发送带有Websocket握手请求的Cookie。我尝试了现有的SockJS,其中cookie由负载均衡器在其他请求上设置,或者在发送Websocket请求的文档中显式设置,然后立即发送请求。

我尝试了简单的key=val cookie,以及具有其他各种选项集组合的cookie,例如pathdomainmax-agesecuresamesite

在任何站点(例如https://www.google.com)上的Chrome开发工具控制台中,执行:

document.cookie = 'key=val'
new WebSocket('wss://www.google.com')

请注意,如果在wss上浏览页面,则方案必须为https;在ws上浏览页面时,方案必须为http。另外,如正在生成的请求中的origin标头所示,域和端口在正在查看的页面和Websocket的URL中是相同的。

检查结果请求(400错误请求-我只关心为该测试生成的请求,而不是结果),它显示:

GET wss://www.google.com/ HTTP/1.1
Host: www.google.com
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: https://www.google.com
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Sec-WebSocket-Key: HrtpryMAlu5yjGCNgxzcpw==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

在Firefox中执行相同的操作,cookie随握手请求发送:

Host: www.google.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Sec-WebSocket-Version: 13
Origin: https://www.google.com
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: QvNsHgLE5znjaUG04RFdPA==
DNT: 1
Connection: keep-alive, Upgrade
Cookie: <SNIPPED>; key=val
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

和Safari:

Connection: Upgrade
Host: www.google.com
Origin: https://www.google.com
Cookie: key=val; <SNIPPED>
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: zQEpYp+yzf5EQmQSb71B6g==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15

我希望生成的请求将包含浏览器已知的所有匹配来源的文档cookie。

我在网上找到了几处参考资料,似乎表明“现代浏览器,包括Chrome”应该是这种情况:

我发现一个参考似乎表明Chrome浏览器没有通过握手请求发送cookie:

我找不到任何官方文档,也没有更改Chrome来解释所观察到的行为。

3 个答案:

答案 0 :(得分:0)

更新2:我将复制通过错误报告发现的内容:

使用UI阻止Cookie并为我的域编辑白名单例外(与禁用Cookie的位置相同),我发现了以下内容:

wss://example.com是“无效的网址”,无法添加。

可以为方案输入*://或为端口输入**,但是会从字符串中删除,结果是:

*:// [*。] example.com:443-> [*。] example.com:443-不起作用

*:// [*。] example.com:*-> [*。] example.com-有效

*://example.com:*-> example.com-有效


更新1:我提交了一个错误报告,并且已得到确认:

https://bugs.chromium.org/p/chromium/issues/detail?id=947413


对我有用的是在设置中全局允许cookie。

是的,这是非常可行的解决方法,因为我永远都不会允许将曾经制作到您的浏览器中的每个cookie称为可接受的解决方案,但是我相当确定这是一个错误。我知道它曾经在不久前通过Cookie阻止+白名单工作,但是当我将它单独放置x周后,某些版本将其破坏了。抱歉,不知道...我不使用Chrome,所以我不在乎,但是也许这样做的人可以在Firefox中执行个人资料之类的事情,并在启用此选项的情况下创建开发者,而永远不会Facebook。

具体来说,在我的Chrome版本中,它位于非常狭窄的汉堡菜单->设置->高级->内容设置...-> Cookies->第一个切换选项(在“允许保存和读取网站之间切换Cookie数据(推荐)”和“已阻止”)。或单击地址栏中的cookie图标,然后单击管理。

我正在Debian 9中使用Linux版本的Chrome版本73.0.3683.86(正式版本)(64位)。您似乎正在使用Mac OS,因此如果这些版本是有点相关。在Windows版本中似乎没有出现此问题,但是我不是自己使用它或对其进行测试的人,它可能会更旧(我可以在以后发现时进行编辑)。它也可以在Android(版本73.0.3683.90)中使用,但是似乎没有一个选项可以首先阻止cookie。

我也尝试了各种设置,但不确定5字形修饰符是否可以检查14000次,但已经有很多天试图弄清这一点。我一遍又一遍地分析了标头和两端的代码,以为可能是Cookie域/路径/到期/ httponly /安全/相同站点,不匹配的域,证书问题,服务器设置等,等等,但是没有,这是一个愚蠢的复选框。至少我可以继续,而不必等待Google对其进行修复...

答案 1 :(得分:0)

cookie可能实际上是在WebSocket Request标头中发送的,只是没有显示在dev-tool中。 Chrome NetLog可以跟踪它。根据他们在此Chromium issue中的建议:

Cookie故意从devtools中显示的标头中过滤掉。这是因为它们是通过渲染器传递的,该渲染器不应访问HttpOnly cookie。

答案 2 :(得分:0)

尝试打开chrome://flags,并禁用SameSite by default cookiesCookies without SameSite must be secure这两个配置。

您可以通过 Wireshark 或任何抓包工具在请求头中看到 cookie,但在 chrome 的开发工具中看不到 cookie。