Где лучше устанавливать куки с JWT: на клиенте или сервере?
При разработке аутентификации с использованием JWT (JSON Web Token) перед разработчиками часто встаёт вопрос: где устанавливать куки - на стороне клиента (JavaScript) или на стороне сервера (HTTP-заголовки). Оба подхода имеют свои плюсы и минусы, особенно в контексте безопасности и удобства работы с фронтенд-разработчиками. Давайте разберёмся, какой вариант предпочтительнее для защиты от XSS-атак и других угроз.
Безопасность установки куки на клиенте
Установка куки с JWT через JavaScript на клиенте (например, document.cookie = 'token=...') делает токен доступным для любых скриптов, выполняющихся на странице. Если сайт подвержен XSS-атаке (межсайтовый скриптинг), злоумышленник может украсть токен, используя тот же JavaScript. Это серьёзная уязвимость, так как JWT часто содержит идентификатор пользователя и права доступа.
Частично проблему решают флаги HttpOnly и Secure, но они не могут быть установлены через клиентский JavaScript - их добавляет только сервер при отправке HTTP-заголовка Set-Cookie. Таким образом, установка куки на клиенте оставляет токен уязвимым для XSS.
Преимущества установки куки на сервере
Когда сервер устанавливает куки через заголовок Set-Cookie, он может добавить флаг HttpOnly. Этот флаг запрещает доступ к куки из JavaScript, что значительно снижает риск кражи JWT даже при XSS-уязвимости. Дополнительно можно использовать флаги Secure (только по HTTPS) и SameSite (защита от CSRF-атак).
Серверный подход также упрощает управление сессиями: удаление куки происходит на сервере, что гарантирует немедленный выход пользователя из системы. Кроме того, это единообразный метод, не зависящий от особенностей клиентского кода.
Почему фронтенд-разработчики предпочитают клиентскую установку?
Многие фронтенд-специалисты привыкли работать с куками через JavaScript, так как это даёт больше контроля над их сроком жизни и содержимым. Они могут не знать, что сервер также может устанавливать куки, или считать это менее гибким. Однако для безопасности приложения с JWT лучше договориться с командой и перейти на серверную установку, объяснив риски XSS.
Если фронтенд-разработчик настаивает на клиентской установке, можно использовать компромисс: хранить JWT в памяти (переменной JavaScript) или в sessionStorage (не доступен между вкладками), а куки использовать только для рефреш-токенов с флагом HttpOnly. Но это усложняет архитектуру.
Лучшая практика для JWT и куки
Рекомендуемый подход для современных веб-приложений:
- Устанавливайте куки с JWT на сервере с флагами
HttpOnly,Secure,SameSite=StrictилиSameSite=Lax. - Используйте короткоживущие access-токены (15-30 минут) и долгоживущие refresh-токены, которые также хранятся в HttpOnly куках.
- Избегайте хранения JWT в localStorage - он уязвим для XSS так же, как и клиентские куки.
- Настройте CSRF-защиту (например, через SameSite или CSRF-токены), так как куки автоматически отправляются с запросами.
Таким образом, установка куки на стороне сервера значительно безопаснее, чем на клиенте. Если ваш фронтенд-разработчик не знаком с этим методом, проведите небольшой ликбез: объясните, что Set-Cookie с HttpOnly - это стандарт индустрии для защиты JWT.