Где лучше устанавливать куки с 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.

    Часто задаваемые вопросы