JWT: что это и как работает — простое объяснение с примерами на PHP
Что такое JWT?
JWT (JSON Web Token) — это способ безопасно передавать данные между двумя сторонами, например, между клиентом и сервером. Представь, что это как паспорт или пропуск, который подтверждает твою личность и права.
В отличие от сессий, где данные хранятся на сервере, JWT — это самодостаточный токен, который содержит информацию о пользователе и подписан, чтобы никто не мог его подделать.
Из чего состоит JWT?
JWT состоит из трёх частей, разделённых точками:
- Header (заголовок) — содержит тип токена и алгоритм подписи. Обычно это что-то вроде:
{
"alg": "HS256",
"typ": "JWT"
}
- Payload (полезная нагрузка) — содержит данные (клеймы), например, ID пользователя, имя и время жизни токена:
{
"userId": 123,
"name": "otets",
"exp": 1712345678
}
- Signature (подпись) — цифровая подпись, которая создаётся на основе header и payload с помощью секретного ключа. Она нужна, чтобы никто не мог изменить содержимое токена.
Всё это кодируется в base64url и соединяется точками — получается строка вида:
header.payload.signature
Как работает JWT?
-
Пользователь логинится и отправляет серверу свои данные.
-
Сервер проверяет пользователя и создаёт JWT с нужными данными, подписывая его секретом.
-
Клиент получает токен и сохраняет, например, в localStorage или куки.
-
При каждом запросе клиент отправляет токен в заголовке Authorization.
-
Сервер проверяет подпись токена, убеждается, что он не изменён и не истёк.
-
Если всё в порядке — даёт доступ к защищённым данным.
Пример создания и проверки 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
- Используй сложный секретный ключ и меняй его при необходимости
- Всегда проверяй подпись и срок жизни токена
- Не храни в payload пароли и приватные данные
- Используй HTTPS для передачи токенов
- Если нужно, реализуй механизм отзыва токенов (черный список)
Заключение
JWT — это мощный и удобный инструмент для авторизации и передачи данных. Если использовать его правильно — ты получишь быстрое, масштабируемое и безопасное решение для своего приложения.
Теперь ты знаешь, что внутри JWT, как его делать и проверять, и почему он так популярен. Поехали, бро, сделай свой проект с JWT и будь круче всех!
P.S. Кстати, если хочешь — на jwt.io можно легко разбирать и проверять токены вживую!