Что такое JWT (JSON Web Token)?

«Что такое JWT (JSON Web Token)?» — вопрос из категории Безопасность, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Структура токена: JWT состоит из трёх частей, разделённых точками и закодированных в Base64Url:

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

Пример создания и проверки JWT в PHP с использованием библиотеки firebase/php-jwt:

use FirebaseJWTJWT;
use FirebaseJWTKey;

// Секретный ключ (для алгоритма HS256)
$secretKey = 'your-secret-key';

// 1. Создание (кодирование) токена
$payload = [
    'iss' => 'your-app.com', // Издатель
    'aud' => 'api.your-app.com', // Аудитория
    'iat' => time(), // Время выдачи
    'exp' => time() + 3600, // Истекает через час
    'user_id' => 123,
    'role' => 'admin'
];

$jwt = JWT::encode($payload, $secretKey, 'HS256');
echo "Созданный токен: $jwtn";

// 2. Проверка и декодирование токена (на стороне API)
try {
    $decoded = JWT::decode($jwt, new Key($secretKey, 'HS256'));
    // $decoded теперь объект с данными из payload
    echo "User ID: " . $decoded->user_id . "n";
    echo "Role: " . $decoded->role . "n";
} catch (Exception $e) {
    // Токен невалиден: просрочен, подпись не совпадает и т.д.
    http_response_code(401);
    echo 'Ошибка аутентификации: ' . $e->getMessage();
}

Типичное использование в HTTP-запросах: Токен передаётся в заголовке Authorization:

Authorization: Bearer <ваш.jwt.токен>

Преимущества и недостатки:

  • Преимущества: Стандартизирован, компактен, самодостаточен (несёт данные), не требует хранения состояния на сервере (stateless).
  • Недостатки: Размер (больше, чем у случайной строки), невозможность немедленного отзыва без дополнительных механизмов (чёрные списки — blacklist), необходимость надёжно хранить секретный ключ.

Безопасность:

  • Никогда не храните конфиденциальные данные (пароли) в payload, так как он легко декодируется.
  • Всегда проверяйте подпись и стандартные claims (exp, iss, aud).
  • Для критичных систем рассмотрите использование короткого времени жизни токена (access token) в паре с механизмом обновления (refresh token).

Видео-ответы