JWT: что это и как работает — простое объяснение с примерами на PHP

отец

Что такое JWT?

JWT (JSON Web Token) — это способ безопасно передавать данные между двумя сторонами, например, между клиентом и сервером. Представь, что это как паспорт или пропуск, который подтверждает твою личность и права.

В отличие от сессий, где данные хранятся на сервере, JWT — это самодостаточный токен, который содержит информацию о пользователе и подписан, чтобы никто не мог его подделать.


Из чего состоит JWT?

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

  1. Header (заголовок) — содержит тип токена и алгоритм подписи. Обычно это что-то вроде:
{
  "alg": "HS256",
  "typ": "JWT"
}
  1. Payload (полезная нагрузка) — содержит данные (клеймы), например, ID пользователя, имя и время жизни токена:
{
  "userId": 123,
  "name": "otets",
  "exp": 1712345678
}
  1. Signature (подпись) — цифровая подпись, которая создаётся на основе header и payload с помощью секретного ключа. Она нужна, чтобы никто не мог изменить содержимое токена.

Всё это кодируется в base64url и соединяется точками — получается строка вида:

header.payload.signature


Как работает JWT?

  1. Пользователь логинится и отправляет серверу свои данные.

  2. Сервер проверяет пользователя и создаёт JWT с нужными данными, подписывая его секретом.

  3. Клиент получает токен и сохраняет, например, в localStorage или куки.

  4. При каждом запросе клиент отправляет токен в заголовке Authorization.

  5. Сервер проверяет подпись токена, убеждается, что он не изменён и не истёк.

  6. Если всё в порядке — даёт доступ к защищённым данным.


Пример создания и проверки JWT на PHP

// Секретный ключ для подписи
$secretKey = 'мой_секретный_ключ';

// Заголовок
$header = base64_encode(json_encode(['alg' => 'HS256', 'typ' => 'JWT']));

// Данные
$payload = base64_encode(json_encode([
    'userId' => 42,
    'name' => 'otets',
    'exp' => time() + 3600  // срок жизни токена — 1 час
]));

// Подпись
$signature = hash_hmac('sha256', "$header.$payload", $secretKey, true);
$signatureEncoded = rtrim(strtr(base64_encode($signature), '+/', '-_'), '=');

// Итоговый токен
$jwt = "$header.$payload.$signatureEncoded";

echo "Твой JWT: $jwt";

Как проверить JWT и получить данные из него?

// Получаем JWT из заголовка Authorization
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
    $jwt = $matches[1];
    list($headerB64, $payloadB64, $signatureB64) = explode('.', $jwt);

    $expectedSignature = hash_hmac(
        'sha256',
        "$headerB64.$payloadB64",
        $secretKey,
        true
    );
    $expectedSignatureB64 = rtrim(strtr(base64_encode($expectedSignature), '+/', '-_'), '=');

    if (hash_equals($expectedSignatureB64, $signatureB64)) {
        $payload = json_decode(base64_decode($payloadB64), true);
        
        if ($payload['exp'] < time()) {
            echo "Токен просрочен";
        } else {
            echo "Привет, " . htmlspecialchars($payload['name']);
        }
    } else {
        echo "Неверная подпись токена";
    }
} else {
    echo "Токен не найден";
}

Почему JWT удобен и безопасен?

  • Самодостаточность — серверу не нужно хранить сессии, вся информация внутри токена.
  • Подпись защищает от подделки — если кто-то поменяет данные, подпись не совпадёт.
  • Стандартизирован — JWT используется в сотнях сервисов и приложений.
  • Легко масштабируется — работает в распределённых системах без общего хранилища сессий.

Но есть и подводные камни

  • ⚠️ Токен нельзя отозвать, пока не истёк (если только делать черный список).
  • ⚠️ Payload не шифруется, а только кодируется — не клади туда секретные данные.
  • ⚠️ Нельзя передавать слишком много данных — токен должен быть лёгким.

Лучшие практики использования JWT

  1. Используй сложный секретный ключ и меняй его при необходимости
  2. Всегда проверяй подпись и срок жизни токена
  3. Не храни в payload пароли и приватные данные
  4. Используй HTTPS для передачи токенов
  5. Если нужно, реализуй механизм отзыва токенов (черный список)

Заключение

JWT — это мощный и удобный инструмент для авторизации и передачи данных. Если использовать его правильно — ты получишь быстрое, масштабируемое и безопасное решение для своего приложения.

Теперь ты знаешь, что внутри JWT, как его делать и проверять, и почему он так популярен. Поехали, бро, сделай свой проект с JWT и будь круче всех!


P.S. Кстати, если хочешь — на jwt.io можно легко разбирать и проверять токены вживую!

JWT Авторизация Безопасность Web Tokens PHP
Просмотров: 0