Где можно хранить JWT токен на клиенте?

Ответ

Выбор места хранения JWT на клиенте — это компромисс между безопасностью и удобством. Вот основные варианты, отсортированные от наиболее до наименее безопасных:

1. HTTP-Only Cookie (Рекомендуемый способ для веб-приложений)

  • Как: Сервер устанавливает cookie с флагами HttpOnly, Secure, SameSite=Strict.
  • Плюсы: Недоступен для JavaScript, что защищает от XSS-атак. Автоматически отправляется браузером с каждым запросом.
  • Минусы: Требует защиты от CSRF-атак (используйте анти-CSRF токены).

2. In-Memory (Переменная JavaScript)

  • Как: Токен сохраняется в переменной (например, в замыкании, состоянии SPA-фреймворка) после логина.
  • Плюсы: Максимальная защита от XSS, так как токен не сохраняется персистентно и очищается при закрытии вкладки.
  • Минусы: Пользователь должен логиниться заново после обновления страницы. Не подходит для PWA или фоновых обновлений.

3. Session Storage

  • Как: sessionStorage.setItem('jwt', token)
  • Плюсы: Данные живут только в рамках вкладки браузера, очищаются после её закрытия.
  • Минусы: Уязвим к XSS (скрипт может прочитать токен). Не сохраняется между сессиями.

4. Local Storage (Наименее безопасный)

  • Как: localStorage.setItem('jwt', token)
  • Плюсы: Простота, токен сохраняется после закрытия браузера.
  • Минусы: Крайне уязвим к XSS. Любой успешный XSS-скрипт получит доступ к токену. Не рекомендуется для хранения чувствительных данных.

Практический совет: Для SPA (React, Angular, Vue) предпочтительна комбинация:

  1. Использовать HTTP-Only Cookie для Access Token.
  2. Хранить в памяти или sessionStorage только идентификатор пользователя или роли для UI-логики.
  3. Реализовать механизм Refresh Tokens (также в HTTP-Only cookie) для получения новых Access Tokенов без повторного логина.

Ответ 18+ 🔞

Слушай, а ведь эта тема с хранением JWT — она как та самая история про Герасима и Муму, только в мире фронтенда. То есть либо ты максималист и делаешь всё по уму, либо потом плачешь, как дурак, когда у тебя токены уплывают к левым людям. Давай разберём, как не оказаться в роли того самого Герасима, который потом будет метаться и орать «Муму!», но уже поздно.

1. HTTP-Only Cookie (Это как спрятать золото в сейф, а ключ выкинуть)

  • Как делается: Сервер тебе в ответ, после того как ты правильно назвал пароль, говорит: «Держи, браток, печеньку». И ставит её с такими флагами: HttpOnly, Secure, SameSite=Strict. Это как если бы тебе вручили пропуск на завод, но вшили его под кожу — руками не достанешь.
  • Плюсы: JavaScript до этой печеньки не доберётся, хоть тресни. Это главный щит от XSS-атак, когда какой-то скрипт-мудак пытается стырить твой токен. Браузер сам, автоматом, прикладывает эту печеньку к каждому запросу на сервер.
  • Минусы: Но есть другая беда — CSRF. Это когда тебя обманом заставляют отправить запрос от твоего же авторизованного браузера. Защита — ставить анти-CSRF токены. Без этого — пиши пропало.

2. In-Memory (Хранить в голове, как самую страшную тайну)

  • Как делается: Получил токен после логина — и запихнул его в какую-нибудь переменную JavaScript. В замыкание, в стейт React'а, куда угодно, лишь бы только скрипт знал.
  • Плюсы: Это, блядь, максимальная защита от XSS. Токен живёт только в оперативке. Закрыл вкладку — и всё, токен испарился, как твои надежды на лёгкую пятницу.
  • Минусы: Пользователь обновил страницу — ему снова логиниться. Фоновые обновления в PWA? Забудь. Это для параноиков, которые не верят даже собственному коду.

3. Session Storage (Чулан, который сгорает вместе с домом)

  • Как делается: sessionStorage.setItem('jwt', token). Проще некуда.
  • Плюсы: Токен живёт ровно столько, сколько открыта вкладка. Закрыл — и след простыл. Удобно для временщиков.
  • Минусы: Но если XSS-скрипт проберётся на страницу, он этот чулан взломает за секунду. И токен твой. И сессия твоя. Всё твоё.

4. Local Storage (Оставить ключи от квартиры под ковриком с надписью «Ключи тут»)

  • Как делается: localStorage.setItem('jwt', token). Первое, что приходит в голову ленивому разработчику.
  • Плюсы: Охуенно просто. Токен переживёт даже перезагрузку компа. Удобно, ёпта.
  • Минусы: А теперь внимание, это ПИЗДЕЦ КАК ОПАСНО. Любой, абсолютно любой XSS-скрипт, который выполнится на твоём сайте, может сделать localStorage.getItem('jwt') и упереть твой токен. Это как хранить паспорт на лавочке у подъезда. НЕ ДЕЛАЙ ТАК С ЧУВСТВИТЕЛЬНЫМИ ДАННЫМИ. ВООБЩЕ.

Так что же делать, ёпта? Практический совет для SPA (React, Vue, Angular):

  1. Основной метод — HTTP-Only Cookie для Access Token. Это наш Герасим, который силён и молчалив, его не сломаешь просто так.
  2. В памяти или в sessionStorage храни только то, что нужно для отображения интерфейса — ID пользователя, его роли. Не сам токен, блядь!
  3. Чтобы пользователя не выкидывало каждый час, реализуй Refresh Tokens. Их тоже отдавай в HTTP-Only Cookie. Пусть сервер тихо, на кухне, обновляет Access Token, когда тот протухнет, а пользователь даже не заметит.

Вот и весь расклад. Не будь распиздяем, не суй токен куда попало. А то потом будешь как тот самый Герасим — смотреть в пустоту и мычать «Муму...», когда твои пользовательские данные уже уплыли в закат.