Содержание

Для веб-приложения, где фронтенд и бэкенд работают на одном домене, надёжнее всего сессии в защищённой cookie: они просты, их легко отозвать, и браузер сам защищает их от кражи скриптами. JWT удобны для мобильных приложений и обмена между сервисами, но требуют продуманного отзыва и хранения. OAuth и OpenID Connect — не альтернатива им, а стандарт входа через внешнего провайдера и выдачи доступа сторонним приложениям.

Разберём, чем подходы отличаются, когда какой выбирать и какие ошибки встречаются чаще всего.

Чем аутентификация отличается от авторизации?

Аутентификация отвечает на вопрос «кто это», а авторизация — «что ему можно». Сессии, JWT и OAuth решают в основном первую задачу и передачу этой информации между запросами; проверка прав на конкретные данные и действия — отдельный слой, который нужен при любом способе входа.

Именно ошибки авторизации — когда пользователь получает доступ к чужим данным — возглавляют список рисков в OWASP Top 10. Поэтому выбор механизма входа не отменяет проверки прав в каждом запросе.

Как работают сессии, JWT и OAuth?

Сессия хранит состояние входа на сервере, а браузер передаёт только её идентификатор в cookie. JWT — подписанный токен, в котором сами данные о пользователе, поэтому сервер может проверить его без обращения к хранилищу. OAuth и OpenID Connect описывают, как получить такие токены от провайдера идентификации — Google, корпоративного каталога или собственного сервера авторизации.

Критерий Сессии в cookie JWT OAuth / OpenID Connect
Где хранится состояние На сервере В самом токене У провайдера идентификации
Отзыв доступа Мгновенный: удалить сессию Сложнее: токен живёт до истечения Через провайдера и короткие токены
Защита от XSS HttpOnly-cookie недоступна скриптам Зависит от места хранения токена Зависит от реализации клиента
Подходит для Веб на одном домене Мобильные приложения, сервисы между собой Вход через внешних провайдеров, доступ третьих сторон
Сложность Низкая Средняя Высокая, лучше готовые решения

Смартфон со значком замка на рабочем столе Фото: Unsplash

Когда выбирать сессии?

Сессии стоит выбирать для веб-приложения, где фронтенд и API находятся на одном домене или поддоменах одного домена. Это самый простой и безопасный вариант: cookie с флагами HttpOnly, Secure и SameSite недоступна скриптам, а выход и блокировка пользователя срабатывают мгновенно.

// config/session.php — безопасные настройки cookie сессии
'secure'    => true,   // только по HTTPS
'http_only' => true,   // недоступна JavaScript
'same_site' => 'lax',  // защита от межсайтовых запросов
'lifetime'  => 120,    // минут бездействия до выхода

SPA на Vue или React на том же домене тоже удобно авторизовать сессиями — во многих фреймворках для этого есть готовые пакеты, например Sanctum в Laravel.

Когда нужны JWT и OAuth?

JWT нужны, когда клиент не может надёжно работать с cookie или запрос проходит через несколько сервисов: мобильные приложения, API для партнёров, обмен между микросервисами. OAuth и OpenID Connect нужны, когда пользователи входят через внешний аккаунт или стороннее приложение получает доступ к данным от имени пользователя.

Правила работы с JWT

  1. Короткий срок жизни токена доступа — минуты, а не дни.
  2. Токен обновления хранится надёжно и может быть отозван на сервере.
  3. В мобильном приложении токены — в защищённом хранилище системы, в браузере — не в localStorage.
  4. Подпись проверяется всегда, алгоритм задаётся на сервере, а не берётся из токена.
  5. В токене нет секретных данных — его содержимое может прочитать любой.

Реализовывать OAuth-сервер самостоятельно почти никогда не стоит: для этого есть готовые провайдеры идентификации и проверенные библиотеки.

Какие ошибки встречаются чаще всего?

Чаще всего ошибаются в хранении токенов, сроках их жизни и проверке прав: токен лежит в localStorage и крадётся при XSS, живёт месяц и не отзывается, а сервер проверяет, что пользователь вошёл, но не проверяет, что объект принадлежит ему.

Типичные ошибки:

  • JWT без механизма отзыва — уволенный сотрудник сохраняет доступ до истечения токена;
  • пароли без медленного хеширования или без ограничения попыток входа;
  • отсутствие двухфакторной аутентификации для администраторов;
  • разные механизмы входа для веба и API без единой проверки прав;
  • сообщения об ошибках входа, по которым можно узнать, существует ли пользователь.

Как проектировать API, чтобы права проверялись единообразно, мы разбирали в статье как спроектировать REST API.

Коротко

  • Аутентификация — кто пользователь, авторизация — что ему можно; права проверяются в каждом запросе.
  • Для веба на одном домене лучший выбор — сессии в HttpOnly-cookie.
  • JWT — для мобильных приложений и обмена между сервисами, с коротким сроком жизни и отзывом.
  • OAuth и OpenID Connect — для входа через внешних провайдеров; используйте готовые решения.
  • Не храните токены в localStorage и включите двухфакторную аутентификацию для администраторов.

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

  • Можно ли хранить JWT в localStorage?

    Не стоит: при любой XSS-уязвимости скрипт злоумышленника прочитает токен. В браузере надёжнее HttpOnly-cookie, в мобильном приложении — защищённое хранилище системы.

  • Нужна ли двухфакторная аутентификация?

    Для администраторов и сотрудников с доступом к данным клиентов — обязательно. Для обычных пользователей её стоит предлагать, а в финансовых продуктах часто требовать.

  • Что такое passkeys?

    Это вход без пароля на основе криптографических ключей, которые хранятся на устройстве пользователя и подтверждаются биометрией или PIN-кодом. Passkeys устойчивы к фишингу и постепенно становятся стандартом входа.