Добавление заголовка Authorization в EventSource HTML5
Быстрый ответ
Знакомьтесь со специфичным API — EventSource
, что является своеобразным Дэвидом Блейном в мире JavaScript. Несмотря на множество перспектив, этот API не поддерживает настройку заголовков.
Однако не стоит отчаиваться, есть способ борьбы с этим ограничением — техника работы с запросами в строковом формате:
// Как фокусы Дэвида Блейна, так и наш токен скрываются (в URL)
const eventSource = new EventSource(`https://example.com/events?token=${encodeURIComponent('YOUR_TOKEN')}`);
Если вам нужен более утончённый подход, обратите внимание на cookie
. Реализация выглядит так:
// Как Санта Клаус, наш токен пролетает через cookie. Тишина!
document.cookie = `token=${encodeURIComponent('YOUR_TOKEN')}`;
const eventSource = new EventSource('https://example.com/events');
Этот подход позволяет скрыть токен от URL, защищая его от возможного разглашения и активируя использование cookies только при необходимости.
Защищённое использование EventSource с помощью краткосрочных токенов и валидации на стороне PHP
Что вы скажете на защитный шлем для вашей SSE-системы? Внедрите краткосрочные токены, о которых знает только PHP, что позволит отсеивать нежелательные запросы.
Обеспечение стабильных SSE-соединений с помощью токенов для пересоединения
Используйте lastEventId
как краткосрочный токен, чтобы восстановить EventSource
-соединение после его обрыва на клиентской стороне:
// Когда соединение обрывается, на помощь приходит lastEventId
const eventSource = new EventSource(`https://example.com/events?lastEventId=${encodeURIComponent('LAST_KNOWN_EVENT_ID')}`);
На серверной стороне присваивайте уникальные идентификаторы каждому событию. Это обеспечит безопасность и непрерывный поток событий.
Передача токенов через lastEventId
Применяйте lastEventId
для отправки аутентификационных токенов. Это простое и безопасное решение:
// lastEventId — не только ориентир, но также и ваш токен
if (eventSource.readyState === EventSource.OPEN) {
eventSource.lastEventId = 'YOUR_SHORT_LIVED_TOKEN';
}
Расширение возможностей: интеграция полифилов для поддержки заголовков
Если возможности браузера оказываются недостаточными, используйте полифилы. Вы можете выбрать, например, "Yaffle/EventSource" — это надежный полифил, который поддерживает пользовательские заголовки:
// Немного полифила, и ваши заголовки будут приняты
const eventSource = new EventSourcePolyfill('https://example.com/events', {
headers: {
'Authorization': `Bearer ${yourToken}`
}
});
Благодаря полифилам, вы сможете настроить наиболее комфортную работу с AngularJS и его интерцепторами.
Альтернативы на основе fetch для поддержки дополнительных заголовков
Попробуйте fetch-event-source
, версию EventSource на базе fetch, которая предоставляет более гибкое управление и повышает защиту данным авторизации:
// Более динамичен, чем игра "принеси"
const eventSourceWithHeaders = fetchEventSource(yourSSEndpoint, {
headers: {
'Authorization': `Bearer ${yourToken}`
},
onmessage(message) {
console.log('Received a new message:', message.data);
},
onopen() {
console.log('Connection opened');
},
onerror(error) {
console.log('Error:', error);
}
});
Этот метод дает возможность использовать множество заголовков и детально настроить SSE для обеспечения безопасности.
Продолжаем изучение: обработка ошибок, управление сообщениями и клиентская безопасность
Передача токенов через URL не безопасна! Используйте cookies
для их перенаправления, если сервер аутентификации и SSE-сервер находятся в одном домене. Это исключит возможность несанкционированного доступа.
С таким подходом передача данных производится через защищенный канал.
Укрепление мер безопасности
Чтобы защититься от атаки "человек посередине", передавайте конфиденциальные данные, вроде токенов, через SSL. Обеспечьте шифрование токенов на сервере. Все это поднимет уровень клиентской безопасности.
Обработка ошибок и управление входящими сообщениями
Распределите обработчики onmessage
и onerror
таким образом, чтобы контролировать поток данных и пресекать возможные проблемы соединения:
// В хороший день обрабатываем сообщения
eventSource.onmessage = function(event) {
// Обработка входящего сообщения.
};
// В плохой день – обрабатываем ошибки
eventSource.onerror = function(error) {
// Обработка ошибки.
};
Полезные материалы
- Использование серверных событий – Web API | MDN — Подробное руководство по Server-Sent Events для профессионалов JavaScript.
- HTML-стандарт для Server-Sent Events — Знакомство с интерфейсом EventSource в HTML, ничто не должно ускользнуть от вашего внимания.
- RFC 2617 – HTTP Authentication: Basic and Digest Access Authentication — Вникните в механизмы HTTP-аутентификации.
- Can I use... Support tables for HTML5, CSS3, etc. — Узнайте больше о широкой поддержке Server-Sent Events (SSE) в браузерах.
- Refreshing your streams with Server-Sent Events | Articles | web.dev — Реализуйте обновления в реальном времени с помощью SSE.
- GitHub – EventSource/eventsource: EventSource client for Node.js and browsers (polyfill) — Полифил, который станет надежным помощником в освоении Server-Sent Events.