JSON Web Token

JSON Web Token

Что такое JSON Web Token?

JWT / JSON Web Token [dʒɒt] - это открытый стандарт (RFC 7519) для создания токенов доступа, основанный на формате JSON, используется для передачи данных для аутентификации в клиент-серверных приложениях. Токены создаются сервером, подписываются секретным ключом и передаются клиенту, который в дальнейшем использует данный токен для подтверждения своей личности.

Состоит из трех сущностей: header, payload и signature - сконкатенированных через точку (“.”).

Идентификация, Аутентификация, Авторизация

  • Идентификация - процедура распознавания субъекта по его идентификатору.
  • Аутентификация - процедура проверки подлинности данных (проверяем, что в базе данных есть пользователь с переданным логином и паролем).
  • Авторизация - предоставление / проверка прав на выполнение определённых действий.

Для простоты запоминания, можно представить обычный проход в офисный центр:

  • идентификация - показать паспорт
  • аутентификация - проверить его подлинность
  • авторизация - разрешить зайти в БЦ, если заказан пропуск на этот паспорт

Схема работы

Как правило, при использовании JSON-токенов в клиент-серверных приложениях реализована следующая схема:

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

Структура

JWT токен состоит из header и payload

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 (Рефреш токен) - эти токены выполняют только одну специфичную задачу — получение нового токена доступа, долгоживущие, но одноразовые.

Зачем нужно два токена

Рассмотрим два примера с похищением токенов:

  1. Если похитили только Access Token - злоумышленник получит доступ только на время жизни токена. Как только оно истечет - владелец воспользуется рефреш токеном и сервер вернет новую пару access и refresh токенов.
  2. Если похитили оба токена - система попросит владельца залогиниться снова, сервер выдаст новые токены, а похищенные перестанут быть валидными. Таким образом, схема refresh + access токен ограничивает время, на которое атакующий может получить доступ к сервису. По сравнению с одним токеном, которым злоумышленник может пользоваться неделями и никто об этом не узнает.

Полезные ресурсы

  • Пять простых шагов для понимания JSON Web Tokens (JWT)
  • Добавляем Refresh Token
  • Зачем нужен Refresh Token, если есть Access Token?
  • Очень подробный Gist