WSS: что это и как использовать защищенный WebSocket

Короткий ответ: wss — это защищенный WebSocket, то есть WebSocket-соединение поверх TLS. Если ws:// похож на HTTP, то wss:// похож на HTTPS. Для публичных сайтов и любых личных данных используйте wss://

Пример:

const socket = new WebSocket("wss://example.com/realtime");

Если страница открыта по HTTPS, а вы пытаетесь подключиться к ws://, браузер может заблокировать соединение как mixed content

ws и wss

ws://:

  • без TLS;
  • подходит для локальной разработки;
  • не годится для передачи личных данных на публичном сайте.

wss://:

  • использует TLS;
  • работает как защищенный канал;
  • нужен для продакшена;
  • совместим с HTTPS-страницами.

Для локальной разработки:

ws://localhost:8080

Для сайта:

wss://aglamov.biz/ws

Что нужно на сервере

Чтобы wss:// работал, сервер или reverse proxy должен иметь TLS-сертификат. Часто схема такая:

Браузер -> wss://site.com/ws -> Nginx/Caddy -> ws://backend:8080

TLS завершается на прокси, а внутренний backend может работать по обычному ws:// внутри закрытой сети

Для Nginx важно прокинуть Upgrade-заголовки:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;

Без этого WebSocket может выглядеть как обычный HTTP-запрос и не подключиться

Как выбрать адрес в JS

Можно строить адрес от текущего протокола страницы:

const protocol = window.location.protocol === "https:" ? "wss" : "ws";
const socket = new WebSocket(`${protocol}://${window.location.host}/ws`);

Так локально страница на HTTP будет подключаться через ws, а продакшен на HTTPS — через wss

Авторизация в wss

wss:// защищает канал, но не решает вопрос: кто подключился. Авторизацию нужно добавить отдельно

Варианты:

  • cookie-сессия, если WebSocket endpoint на том же домене;
  • короткоживущий токен в первом сообщении после open;
  • backend, который проверяет пользователя до upgrade;
  • отдельный gateway для realtime-соединений.

Пример первого auth-сообщения:

socket.addEventListener("open", () => {
  socket.send(JSON.stringify({
    type: "auth",
    token: accessToken,
  }));
});

Не храните долгоживущие секреты в клиентском коде. Если токен утек, wss не спасет от авторизованного злоумышленника с этим токеном

Частые ошибки

Первая ошибка — использовать ws:// на HTTPS-странице. Это частая причина ошибки подключения в браузере

Вторая ошибка — думать, что wss сам авторизует пользователя. Нет, TLS защищает канал, но авторизацию нужно делать отдельно: cookie, токен, сессия или первое auth-сообщение

Третья ошибка — настроить TLS для сайта, но забыть Upgrade на reverse proxy

Четвертая ошибка — тестировать wss://localhost без сертификата. Для локалки проще использовать ws://localhost, если вы не тестируете именно TLS

Пятая ошибка — считать, что wss ускоряет WebSocket. Его задача — безопасность канала. Производительность зависит от сервера, сети, формата сообщений и нагрузки

Проверка

В браузере откройте DevTools -> Network -> WS. Подключение к wss:// должно появиться в списке WebSocket-соединений. Если ошибка есть в Console, проверьте протокол страницы, сертификат, домен и прокси

Через JS:

const socket = new WebSocket("wss://example.com/ws");

socket.addEventListener("open", () => console.log("secure ws open"));
socket.addEventListener("error", () => console.log("secure ws error"));

Локальная разработка и продакшен

Нормальная практика — использовать разные адреса:

const socketUrl =
  import.meta.env.DEV
    ? "ws://localhost:8080"
    : "wss://example.com/ws";

Главное — не зашить локальный ws://localhost в production-сборку. Такая ошибка часто всплывает только после публикации, когда сайт открывается по HTTPS, а приложение все еще пытается подключиться к локальному адресу разработчика

Что почитать дальше по WebSocket

Если нужен общий маршрут по теме, откройте рубрику WebSocket. Для соседних задач пригодятся эти разборы:

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x