Аутентификация на основе токенов

Самый распространенный способ реализации аутентификации на основе токенов — использование JSON Web Tokens (JWTs).

JWT — это открытый стандарт (RFC 7519), определяющий способ безопасной передачи информации между сторонами в виде объектов JSON.

После получения учётных данных от клиента сервер проверяет их и генерирует идентификационный токен JWT, содержащий информацию о пользователе. Токены идентифицируют пользователя и предоставляют данные о событии аутентификации. Они предназначены для клиента и имеют фиксированный формат, который позволяет извлекать идентификационную информацию.

Чтобы предотвратить изменения или подделку, сервер формирует электронную подпись данных токена при его создании и добавляет её в токен. JWT используется в stateless приложениях и не хранится на сервере; клиент отправляет его с запросами.

JWT состоит из трёх частей:

  • Заголовка с типом токена и алгоритмом шифрования.
  • Полезной нагрузки с данными для аутентификации и информацией о пользователе.
  • Подписи, содержащей хешированное значение header+payload+соль, которая подтверждает подлинность данных в полезной нагрузке.

Токен представляет из себя простую строку из символов, например:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Этапы аутентификации с помощью токена:

  1. Ввод логина и пароля.
  2. Шифрование (преобразование логина и пароля в закодированную строку).
  3. Передача шифрованных данных на сервер.
  4. Генерация сервером токена доступа, с помощью которого веб-приложение будет обращаться к backend приложению для получения данных. Этот токен должен отправляться на сервер с каждым запросом.
  5. Отправка токена обратно в браузер.
  6. Сохранение токена на клиенте для дальнейшего использования.

Суть в том, что мы один раз передаём приватные данные, а затем используем токен с публичными данными. Ключ для подписи токена хранится только на сервере, и клиент не имеет к нему доступа, что гарантирует, что только сервер может изменять токен. Декодировать токен и получить header и payload может любой, кто его получил, так как эти данные публичные.

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

Access и Refresh токены

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

Для решения этой проблемы используются Access и Refresh токены. Access Token остаётся, и добавляется Refresh токен с такой же структурой.

Оба токена содержат обязательные поля в полезной нагрузке — iat и exp.

iat (issued at time) — время, когда токен сгенерирован. exp (expiration time) — время, до которого токен будет считаться валидным.

Алгоритм аутентификации с использованием Refresh и Access токенов
  1. Пользователь вводит логин и пароль, которые отправляются на сервер.
  2. Сервер создаёт или находит пользователя в базе данных и генерирует два токена с полями iat и exp: Access Token с коротким сроком действия (15-20 минут) и Refresh Token с более длительным (несколько дней или недель).
  3. Сервер возвращает оба токена в браузер, где они сохраняются.
  4. При запросе данных клиент проверяет срок действия Access Token. Если он не истёк, запрос отправляется; если истёк, необходимо обновить токен перед отправкой.
  5. Для обновления Access Token клиент отправляет запрос с Refresh Token. Сервер генерирует новую пару токенов и возвращает их клиенту.
  6. Если Refresh Token также истёк, возвращается ошибка, и пользователя просят ввести логин и пароль снова.

Дополнительно:

  • https://jwt.io/