Что такое JSON Web Token?
JWT / JSON Web Token [dʒɒt] - это открытый стандарт (RFC 7519) для создания токенов доступа, основанный на формате JSON, используется для передачи данных для аутентификации в клиент-серверных приложениях. Токены создаются сервером, подписываются секретным ключом и передаются клиенту, который в дальнейшем использует данный токен для подтверждения своей личности.
Состоит из трех сущностей: header, payload и signature - сконкатенированных через точку (“.”).
Идентификация, Аутентификация, Авторизация
- Идентификация - процедура распознавания субъекта по его идентификатору.
- Аутентификация - процедура проверки подлинности данных (проверяем, что в базе данных есть пользователь с переданным логином и паролем).
- Авторизация - предоставление / проверка прав на выполнение определённых действий.
Для простоты запоминания, можно представить обычный проход в офисный центр:
- идентификация - показать паспорт
- аутентификация - проверить его подлинность
- авторизация - разрешить зайти в БЦ, если заказан пропуск на этот паспорт
Схема работы
Как правило, при использовании JSON-токенов в клиент-серверных приложениях реализована следующая схема:
- Клиент проходит аутентификацию в приложении (к примеру, с использованием логина и пароля)
- В случае успешной аутентификации сервер отправляет клиенту access- и refresh-токены.
- При дальнейшем обращении к серверу клиент использует access-токен. Сервер проверяет токен на валидность и предоставляет клиенту доступ к ресурсам
- В случае, если access-токен становится невалидным, клиент отправляет refresh-токен, в ответ на который сервер предоставляет два обновленных токена.
- В случае, если refresh-токен становится невалидным, клиент опять должен пройти процесс аутентификации (п. 1).
Структура
JWT токен состоит из header и payload
Header
Header - заголовок содержит информацию о том, как должна вычисляться JWT подпись, это тоже JSON объект, который выглядит следующим образом:
{ "alg": "HS256", "typ": "JWT"}
Описание header:
- Typ - сообщает, что это JSON Web Token.
- Alg - определяет алгоритм хеширования, который будет использоваться при создании подписи. HS256 (HMAC-SHA256) - для его вычисления нужен один секретный ключ. RS256 - ассиметричный и создает два ключа: публичный и приватный. С помощью приватного ключа создается подпись, а с помощью публичного проверяется подлинность подписи.
Payload / JWT-claims
- Payload / JWT-claims (заявки) - полезные данные которые хранятся внутри JWT. Можно указать ID пользователя, его роль и т.д.
{ "ID": "47f575ef-fb6e-44e9-ac84-953e9ba66bae" }
Стандартные заявки:
- iss (issuer) — определяет приложение, из которого отправляется токен.
- sub (subject) — определяет тему токена.
- exp (expiration time) — время жизни токена.
- Signature (подпись) - заголовок и полезная нагрузка кодируются при помощи алгоритма base64url, после чего объединяются в единую строку с использованием точки в качестве разделителя.
Пример
Можно посмотреть на сайте https://jwt.io
Header:
{
"alg": "HS256",
"typ": "JWT"
}
Payload:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Signature:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
Token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Access и refresh токены
- Access Token (Токен доступа) - это токены, с помощью которых можно получить доступ к защищенным ресурсам. Они короткоживущие, но многоразовые. В них может содержаться дополнительная информация.
- Refresh Token (Рефреш токен) - эти токены выполняют только одну специфичную задачу — получение нового токена доступа, долгоживущие, но одноразовые.
Зачем нужно два токена
Рассмотрим два примера с похищением токенов:
- Если похитили только Access Token - злоумышленник получит доступ только на время жизни токена. Как только оно истечет - владелец воспользуется рефреш токеном и сервер вернет новую пару access и refresh токенов.
- Если похитили оба токена - система попросит владельца залогиниться снова, сервер выдаст новые токены, а похищенные перестанут быть валидными. Таким образом, схема refresh + access токен ограничивает время, на которое атакующий может получить доступ к сервису. По сравнению с одним токеном, которым злоумышленник может пользоваться неделями и никто об этом не узнает.
Полезные ресурсы
- Пять простых шагов для понимания JSON Web Tokens (JWT)
- Добавляем Refresh Token
- Зачем нужен Refresh Token, если есть Access Token?
- Очень подробный Gist