Мне нужно отправить файл cookie с запросом рукопожатия websocket, чтобы гарантировать, что балансировщик нагрузки направляет запрос к определенному бэкэнду. Это отлично работает в Firefox, Safari и в веб-сокете, но я не могу заставить Chrome отправлять куки-файлы с запросом рукопожатия в веб-сокете.
Я включил липкие сессии в своем балансировщике нагрузки (Traefik), и он «просто работал» в Firefox и Safari с моим существующим кодом SockJS.
В первом запросе нет файла cookie, и балансировщик нагрузки устанавливает его в ответ на запрос подтверждения связи (101 протокол переключения). Последующие запросы рукопожатия веб-сокета отправляют файл cookie, и получающееся в результате соединение веб-сокета устанавливается на правильный сервер.
В моем клиенте с поддержкой веб-сокетов я явно устанавливаю куки-файл перед открытием соединения, и он работает как положено.
Chrome никогда не отправляет файлы cookie с запросами на рукопожатие. Я пробовал существующий SockJS, с файлами cookie, установленными балансировщиком нагрузки для других запросов или явно установленными в документе, отправляющем запрос websocket непосредственно перед отправкой запроса.
Я пробовал простые key=val
файлы cookie и файлы cookie с различными другими комбинациями параметров, например, path
, domain
, max-age
, secure
, samesite
и т. Д.
В консоли инструментов Chrome dev на любом сайте (например, https://www.google.com), выполнить:
document.cookie = 'key=val'
new WebSocket('wss://www.google.com')
Обратите внимание, что схема должна быть wss
при просмотре страницы более https
или ws
при просмотре страницы более http
. Кроме того, домен и порт идентичны на просматриваемой странице и в 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»:
Я нашел одну ссылку, которая указывает, что Chrome не отправляет куки с запросом на рукопожатие:
Мне не удалось найти официальную документацию или изменения в Chrome для объяснения наблюдаемого поведения.