Как устанавливается WebSocket соединение и какие действия происходят перед двусторонним общением клиента и сервера
Что проверяют
Знаете ли вы, что WebSocket начинается как обычный HTTP-запрос и что именно происходит в рукопожатии. Следом часто спрашивают, зачем нужен Sec-WebSocket-Key и почему фреймы клиента маскируются.
Как отвечать
Перечислите шаги до первого сообщения по порядку:
- сеть: DNS, TCP-соединение, для
wss://ещё TLS-рукопожатие. Всё это происходит до WebSocket; - запрос на апгрейд:
GETпо HTTP/1.1 с заголовкамиUpgrade: websocket,Connection: Upgrade,Sec-WebSocket-Version: 13и случайнымSec-WebSocket-Keyв base64. Браузер сам добавляетOriginи cookie, по желаниюSec-WebSocket-Protocolсо списком подпротоколов иSec-WebSocket-Extensions, обычноpermessage-deflate; - проверка на сервере: сервер смотрит
Origin(единственная защита от подключения с чужого сайта), авторизацию, подпротокол; - ответ 101 Switching Protocols: сервер возвращает
Sec-WebSocket-Accept, это base64 от SHA-1 от ключа клиента, склеенного с фиксированным GUID из RFC 6455. Клиент пересчитывает значение и при несовпадении рвёт соединение. Любой другой статус, например 401 или 403, означает отказ; - фреймы: дальше по тому же TCP идут фреймы с опкодами text, binary, close, ping, pong. Каждый фрейм от клиента маскируется 4-байтным ключом, чтобы промежуточные прокси не приняли содержимое за HTTP и не отравили свой кеш.
Закрытие тоже рукопожатие: сторона шлёт close-фрейм с кодом, вторая отвечает таким же, после чего закрывается TCP. По HTTP/2 WebSocket поднимается через расширенный CONNECT из RFC 8441, но на собеседовании обычно ждут классическую схему через HTTP/1.1.
Где спотыкаются
Считают Sec-WebSocket-Key механизмом безопасности. Это лишь доказательство, что сервер действительно понимает WebSocket, а не случайно ответил кешированной страницей. Шифрования и аутентификации он не даёт.
Путают, кто маскирует. Маскирует только клиент, сервер фреймы не маскирует, и это требование протокола, а не настройка.
Забывают про проверку Origin. Браузер отправляет cookie при подключении с любого сайта, и без проверки на сервере получается cross-site WebSocket hijacking.