【发布时间】:2019-08-17 10:17:52
【问题描述】:
我需要发送一个带有 websocket 握手请求的 cookie,以确保负载均衡器将请求路由到特定的后端。这在 Firefox、Safari 和 websocket-sharp 中运行良好,但我无法让 Chrome 使用 websocket 握手请求发送 cookie。
我在我的负载均衡器 (Traefik) 中启用了粘性会话,它在 Firefox 和 Safari 上使用我现有的 SockJS 代码“正常工作”。
第一个请求没有 cookie,负载均衡器在握手响应上设置了一个(101 切换协议)。随后的 websocket 握手请求发送 cookie,生成的 websocket 连接建立到正确的后端。
在我的 websocket-sharp 客户端中,我在打开连接之前明确设置了 cookie,它按预期工作。
Chrome 从不发送带有 websocket 握手请求的 cookie。我尝试了现有的 SockJS,使用负载均衡器在其他请求上设置的 cookie,或者在发送请求之前立即在发出 websocket 请求的文档中明确设置。
我尝试了简单的key=val cookie,以及带有各种其他选项组合的 cookie,例如path、domain、max-age、secure、samesite等
在任何站点(例如https://www.google.com)的 Chrome 开发工具控制台中,执行:
document.cookie = 'key=val'
new WebSocket('wss://www.google.com')
请注意,如果在https 上查看页面,则方案必须为wss,在http 上查看页面时,方案必须为ws。此外,正在查看的页面和 websocket 的 URL 中的域和端口是相同的,如生成的请求中的 origin 标头中所述。
检查生成的请求(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 的参考资料:
我在 Chrome 中找不到任何官方文档或更改来解释观察到的行为。
【问题讨论】:
标签: google-chrome cookies websocket