Аутентификация на основе токенов
Самый распространенный способ реализации аутентификации на основе токенов — использование JSON Web Tokens (JWTs).
JWT — это открытый стандарт (RFC 7519), определяющий способ безопасной передачи информации между сторонами в виде объектов JSON.
После получения учётных данных от клиента сервер проверяет их и генерирует идентификационный токен JWT, содержащий информацию о пользователе. Токены идентифицируют пользователя и предоставляют данные о событии аутентификации. Они предназначены для клиента и имеют фиксированный формат, который позволяет извлекать идентификационную информацию.
Чтобы предотвратить изменения или подделку, сервер формирует электронную подпись данных токена при его создании и добавляет её в токен. JWT используется в stateless приложениях и не хранится на сервере; клиент отправляет его с запросами.
JWT состоит из трёх частей:
- Заголовка с типом токена и алгоритмом шифрования.
- Полезной нагрузки с данными для аутентификации и информацией о пользователе.
- Подписи, содержащей хешированное значение header+payload+соль, которая подтверждает подлинность данных в полезной нагрузке.
Токен представляет из себя простую строку из символов, например:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Этапы аутентификации с помощью токена:
- Ввод логина и пароля.
- Шифрование (преобразование логина и пароля в закодированную строку).
- Передача шифрованных данных на сервер.
- Генерация сервером токена доступа, с помощью которого веб-приложение будет обращаться к backend приложению для получения данных. Этот токен должен отправляться на сервер с каждым запросом.
- Отправка токена обратно в браузер.
- Сохранение токена на клиенте для дальнейшего использования.
Суть в том, что мы один раз передаём приватные данные, а затем используем токен с публичными данными. Ключ для подписи токена хранится только на сервере, и клиент не имеет к нему доступа, что гарантирует, что только сервер может изменять токен. Декодировать токен и получить header и payload может любой, кто его получил, так как эти данные публичные.
Когда сервер получает токен, он вычисляет подпись полезной нагрузки с помощью своего ключа и сравнивает её с подписью в токене. Если данные не совпадают или не удаётся декодировать токен, это указывает на возможное вмешательство, и запрос не проходит валидацию, возвращая ошибку.
Access и Refresh токены
Подпись токена защищает его от изменений, но хакеры могут перехватить его и использовать для доступа к аккаунту, так как токен содержит все данные для аутентификации. Это делает любого, кто получил токен, равным настоящему владельцу аккаунта.
Для решения этой проблемы используются Access и Refresh токены. Access Token остаётся, и добавляется Refresh токен с такой же структурой.
Оба токена содержат обязательные поля в полезной нагрузке — iat и exp.
iat (issued at time) — время, когда токен сгенерирован. exp (expiration time) — время, до которого токен будет считаться валидным.
Алгоритм аутентификации с использованием Refresh и Access токенов
- Пользователь вводит логин и пароль, которые отправляются на сервер.
- Сервер создаёт или находит пользователя в базе данных и генерирует два токена с полями iat и exp: Access Token с коротким сроком действия (15-20 минут) и Refresh Token с более длительным (несколько дней или недель).
- Сервер возвращает оба токена в браузер, где они сохраняются.
- При запросе данных клиент проверяет срок действия Access Token. Если он не истёк, запрос отправляется; если истёк, необходимо обновить токен перед отправкой.
- Для обновления Access Token клиент отправляет запрос с Refresh Token. Сервер генерирует новую пару токенов и возвращает их клиенту.
- Если Refresh Token также истёк, возвращается ошибка, и пользователя просят ввести логин и пароль снова.
Дополнительно:
- https://jwt.io/