Перейти к содержанию
Innovialabs

Сессии или JWT: как реализовать авторизацию в веб-приложении

Практика3 мин

Коротко

Для обычного веб-приложения надёжный выбор по умолчанию — серверные сессии в httpOnly cookie; JWT с refresh-токенами оправдан для мобильных клиентов, нескольких сервисов и внешних API.

Короткий ответ

  • Сессия: после входа сервер создаёт запись в хранилище (БД, Redis) и отдаёт браузеру случайный ID в cookie. На каждый запрос сервер находит сессию по ID.
  • JWT: сервер выдаёт подписанный токен с данными пользователя и сроком жизни. Проверка — по подписи, без обращения к хранилищу.

Если у вас один сайт и свой бэкенд, начинайте с сессий в httpOnly cookie. Они проще, их легко отозвать, и в них сложнее ошибиться.

Сравнение

Cookie-сессияJWT
Где состояниеНа сервереВнутри токена
Проверка запросаПоиск в хранилищеПроверка подписи
Выход и отзывУдалить запись — и всёСложно до истечения срока
Мобильные приложенияВозможно, но менее удобноЕстественно
Несколько сервисовНужно общее хранилищеКаждый проверяет подпись сам
Риск ошибокНижеВыше: алгоритмы, срок, хранение

Как устроен refresh-поток

Главная проблема JWT — его нельзя «погасить» до истечения срока. Поэтому используют пару токенов:

  1. Access token — короткоживущий, передаётся с каждым запросом.
  2. Refresh token — долгоживущий, хранится надёжно и нужен только для получения нового access token.
  3. Когда access истёк, клиент вызывает /auth/refresh и получает новую пару.
  4. Ротация: при каждом обновлении старый refresh становится недействительным. Если кто-то пытается использовать уже потраченный refresh — это признак кражи, и всю цепочку стоит отозвать.

Обратите внимание: refresh-токены хранятся на сервере, чтобы их можно было отозвать. То есть JWT-схема всё равно возвращается к состоянию на сервере.

Где хранить токены в браузере

  • httpOnly, Secure cookie — JavaScript не может прочитать, значит, XSS не украдёт токен напрямую. Нужна защита от CSRF: SameSite=Lax или Strict и, для изменяющих запросов, CSRF-токен или проверка Origin.
  • localStorage — доступен любому скрипту на странице. Одна XSS-уязвимость — и токен утёк. Для долгоживущих токенов не рекомендуется.
  • Память приложения — допустимо для короткого access token; refresh при этом держат в httpOnly cookie.
Set-Cookie: sid=8f3c...; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=1209600

Выход и отзыв доступа

  • Сессии: удаляете запись — пользователь вышел на всех устройствах или на одном, как решите.
  • JWT: удаляете refresh на сервере, а access доживает свой короткий срок. Для мгновенной блокировки нужен denylist или версия токена у пользователя, которую проверяет сервер.

Обязательно отзывайте все сессии при смене пароля и дайте пользователю список активных устройств.

Рекомендуемая архитектура по умолчанию

  1. Пароли — только в виде хеша медленным алгоритмом (bcrypt, scrypt, Argon2).
  2. Веб-клиент — серверная сессия, ID в cookie HttpOnly; Secure; SameSite=Lax.
  3. Новый ID сессии после входа (защита от фиксации сессии).
  4. Ограничение попыток входа.
  5. Мобильное приложение или внешние интеграции — короткий access JWT + ротируемый refresh, хранимый на сервере.
  6. Проверка прав на каждом запросе на сервере, а не только скрытие кнопок в интерфейсе.

Если не хотите писать всё сами, используйте зрелую библиотеку аутентификации для вашего фреймворка или внешнего провайдера идентификации.

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

  • JWT в localStorage без срока жизни.
  • Чувствительные данные в payload JWT — он подписан, но не зашифрован, его может прочитать кто угодно.
  • Приём токенов с alg: none или без строгой проверки алгоритма.
  • Нет механизма выхода «со всех устройств».

Частые вопросы

Проверка подписи не требует обращения к базе, но поиск сессии в Redis обычно тоже очень быстрый. Для большинства проектов разница несущественна по сравнению с надёжностью и простотой.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.