google-chrome - 如何让 Chrome 使用 WebSocket 握手请求发送 cookie?

标签 google-chrome cookies websocket

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

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

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

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

Chrome 从不发送带有 websocket 握手请求的 cookie。我尝试了现有的 SockJS,使用负载均衡器在其他请求上设置的 cookie,或者在发送请求之前立即在发出 websocket 请求的文档中明确设置。

我试过简单的key=val cookie,以及带有各种其他选项组合的 cookie,例如path , domain , max-age , secure , samesite , ETC。

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

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

注意方案必须是wss如果查看超过 https 的页面, 或 ws当查看超过 http 的页面时.此外,正在查看的页面和 websocket 的 URL 中的域和端口是相同的,如 origin 中所述。生成的请求中的 header 。

检查生成的请求(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”应该是这种情况:
  • https://github.com/crossbario/autobahn-js/issues/88#issuecomment-61367897
  • https://stackoverflow.com/a/43238378/2829685

  • 我发现了一个似乎表明 Chrome 不会在握手请求中发送 cookie 的引用资料:
  • https://stackoverflow.com/a/51468160/2829685

  • 我在 Chrome 中找不到任何官方文档或更改来解释观察到的行为。

    最佳答案

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

    使用 UI 阻止 cookie 并编辑我的域的白名单异常(exception)(与禁用 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 中使用 Chrome 版本 73.0.3683.86(官方构建)(64 位)的 Linux 版本。看起来您使用的是 Mac OS,所以如果这些版本有些相关,这可能也会对您有所帮助。在 Windows 版本中似乎没有出现这个问题,但是我不是使用它或自己测试它的人,它可能更旧(我可以稍后在我发现时进行编辑)。它也适用于 Android(版本 73.0.3683.90),但它似乎一开始就没有阻止 cookie 的选项。

    我也尝试了各种设置,我不确定使用五元组的词修饰符来检查 14000 次,但已经很多天试图弄清楚这一点。我一遍又一遍地分析了两端的 header 和代码,并认为它可能是 cookie 域/路径/过期/httponly/secure/samesite、不匹配的域、证书问题、服务器设置等,等等,但是没有,这是一个愚蠢的复选框。至少我可以继续,不必等待谷歌修复它......

    关于google-chrome - 如何让 Chrome 使用 WebSocket 握手请求发送 cookie?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55367189/

    相关文章:

    css - 带有 Flexbox 的输入元素在 Webkit 中添加了额外的间距

    google-chrome - 谷歌浏览器和网站图标

    html - 为什么这个背景图像在 mozilla 中变暗了?

    asp.net-mvc - Linux 上的 mono 返回不同的 cookie 集

    javascript - 设置 WebSocket 编码

    c# - 是否有任何体面的 Websocket C# 实现?

    html - Favicon 未显示在 Google Chrome 浏览器中

    javascript - 登录成功后获取cookie?

    javascript - $http 响应 Set-Cookie 不可访问

    javascript - 从 "socket"库向 "websockets/ws"对象添加方法