Что такое JWT и каков его принцип работы в системах аутентификации?

Ответ

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

Токен состоит из трёх частей, разделённых точками (.): header.payload.signature

  1. Header (Заголовок): содержит метаданные — тип токена (typ) и алгоритм подписи (alg), например, HS256.
  2. Payload (Полезная нагрузка): содержит утверждения (claims) — данные о пользователе (sub, user_id) и служебную информацию (время жизни exp, время создания iat).
  3. Signature (Подпись): создаётся на основе закодированных header, payload и секретного ключа, хранящегося на сервере. Подпись гарантирует, что токен не был изменён.

Схема работы при аутентификации:

  1. Пользователь отправляет логин и пароль на сервер.
  2. Сервер проверяет учётные данные. В случае успеха он генерирует JWT и отправляет его клиенту.
  3. Клиент сохраняет токен (например, в localStorage или cookie).
  4. При каждом запросе к защищённым ресурсам клиент отправляет токен в HTTP-заголовке Authorization: Authorization: Bearer <your.jwt.token>
  5. Сервер получает токен, проверяет его подпись с помощью своего секретного ключа. Если подпись верна, сервер доверяет данным в payload и предоставляет доступ.

Пример на Python с PyJWT:

import jwt
import time

SECRET_KEY = "your-super-secret-key"

# 1. Создание токена на сервере
payload = {
    "user_id": 123,
    "exp": int(time.time()) + 3600  # Время жизни - 1 час
}
token = jwt.encode(payload, SECRET_KEY, algorithm="HS256")

# 2. Проверка токена на сервере при запросе от клиента
try:
    decoded_payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
    print(f"Доступ разрешен для пользователя: {decoded_payload['user_id']}")
except jwt.ExpiredSignatureError:
    print("Ошибка: срок действия токена истек.")
except jwt.InvalidTokenError:
    print("Ошибка: невалидный токен.")

Ключевое преимущество: JWT-аутентификация является stateless. Серверу не нужно хранить сессии, что упрощает масштабирование.

Основной недостаток: токен нельзя отозвать до истечения его срока действия. Эта проблема обычно решается использованием короткоживущих access-токенов и долгоживущих refresh-токенов.