Как работает JWT-авторизация и из чего состоит токен?

Ответ

JWT (JSON Web Token) — это компактный, URL-безопасный способ представления утверждений, которые должны быть переданы между сторонами. Он часто используется для авторизации и аутентификации в распределенных системах, так как является stateless (не требует хранения сессий на сервере).

Структура JWT:

JWT состоит из трех частей, разделенных точками (.): Header.Payload.Signature.

  1. Header (Заголовок): JSON-объект, содержащий метаданные о токене, такие как тип токена (typ) и используемый алгоритм подписи (alg).

    {
      "alg": "HS256",
      "typ": "JWT"
    }

    Затем кодируется в Base64Url.

  2. Payload (Полезная нагрузка): JSON-объект, содержащий утверждения (claims) — информацию о пользователе или другие данные. Стандартные утверждения включают iss (издатель), exp (срок действия), sub (субъект), aud (аудитория). Можно добавлять и кастомные утверждения.

    {
      "user_id": 123,
      "username": "john.doe",
      "exp": 1735689600, // Срок действия токена (Unix timestamp)
      "role": "admin"
    }

    Также кодируется в Base64Url.

  3. Signature (Подпись): Создается путем хеширования закодированных Header и Payload вместе с секретным ключом сервера. Подпись обеспечивает целостность токена (данные не были изменены) и аутентичность (токен был выдан легитимным сервером).

    HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret_key)

Как работает JWT-авторизация:

  1. Аутентификация: Клиент отправляет учетные данные (логин/пароль) на сервер.
  2. Выдача токена: Сервер проверяет учетные данные. В случае успеха, он генерирует JWT, подписывает его своим секретным ключом и отправляет клиенту.
  3. Хранение токена: Клиент сохраняет полученный JWT (например, в localStorage, sessionStorage или httpOnly cookie).
  4. Авторизация: При каждом последующем запросе к защищенным ресурсам клиент прикрепляет JWT в заголовок Authorization: Bearer <token>.
  5. Валидация токена: Сервер получает запрос, извлекает JWT, проверяет его подпись с помощью своего секретного ключа. Если подпись валидна и токен не истек, сервер доверяет данным в Payload и предоставляет доступ к ресурсу.

Преимущества JWT:

  • Stateless: Серверу не нужно хранить информацию о сессиях, что упрощает масштабирование и работу с микросервисами.
  • Компактность: Токены небольшие и легко передаются.
  • Мобильность: Идеально подходят для мобильных приложений и SPA.

Недостатки и их решения:

  • Невозможность отзыва: Токен нельзя отозвать до истечения срока действия (exp).
    • Решение: Использовать короткоживущие токены в сочетании с refresh-токенами; вести "черные списки" (blacklist) отозванных токенов на сервере.
  • Уязвимость к XSS: Если токен хранится в localStorage, он может быть украден через XSS-атаки.
    • Решение: Хранить токены в httpOnly cookies (защищает от JavaScript-доступа) или использовать более сложные механизмы, такие как CSRF-токены в сочетании с JWT.