JWT токены в PHP: полное руководство по библиотеке firebase/php-jwt
JSON Web Token (JWT) — это компактный и безопасный способ передачи данных между клиентом и сервером в формате JSON. В современной веб-разработке JWT широко используется для аутентификации и авторизации пользователей, а также для обмена информацией между различными сервисами. В PHP наиболее популярной и надёжной библиотекой для работы с JWT является firebase/php-jwt.
Что такое JWT и зачем он нужен?
JWT состоит из трёх частей, разделённых точками:
- Header — заголовок, содержащий информацию о типе токена и алгоритме подписи.
- Payload — полезная нагрузка с данными (например, ID пользователя, роль, срок действия).
- Signature — подпись, созданная с использованием секретного ключа или пары ключей RSA/ECDSA.
Основные преимущества JWT:
- Не требуют хранения сессий на сервере (stateless).
- Могут содержать любые данные в формате JSON.
- Поддерживают различные алгоритмы подписи: HS256, RS256, ES256 и другие.
- Устойчивы к подделке благодаря криптографической подписи.
Установка библиотеки firebase/php-jwt
Для установки библиотеки используйте Composer. Откройте терминал в корневой папке проекта и выполните команду:
composer require firebase/php-jwt
После установки подключите автозагрузку Composer в вашем PHP-скрипте:
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
?>
Создание JWT токена
Для создания токена необходимо определить полезную нагрузку (payload) и подписать её секретным ключом. Пример создания токена с алгоритмом HS256:
<?php
$key = 'your-secret-key-here'; // Секретный ключ (не менее 32 символов)
$payload = [
'iss' => 'pythonlib.ru', // Издатель токена
'sub' => '1234567890', // Субъект (например, ID пользователя)
'name' => 'Иван Иванов',
'role' => 'user',
'iat' => time(), // Время создания
'exp' => time() + 3600 // Срок действия (1 час)
];
$jwt = JWT::encode($payload, $key, 'HS256');
echo "Созданный JWT токен:\n" . $jwt;
?>
В этом примере мы задаём стандартные поля: iss (издатель), sub (субъект), iat (время создания) и exp (срок действия). Вы можете добавлять любые кастомные поля, такие как role или email.
Декодирование и проверка JWT токена
При получении токена от клиента необходимо проверить его подпись и срок действия. Библиотека автоматически проверяет алгоритм и валидность подписи:
<?php
try {
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
print_r($decoded);
} catch (\Firebase\JWT\ExpiredException $e) {
echo "Ошибка: токен истёк — " . $e->getMessage();
} catch (\Firebase\JWT\SignatureInvalidException $e) {
echo "Ошибка: неверная подпись — " . $e->getMessage();
} catch (\Exception $e) {
echo "Ошибка: " . $e->getMessage();
}
?>
Метод decode() возвращает объект stdClass с данными payload. Если токен недействителен, выбрасывается соответствующее исключение. Рекомендуется всегда обрабатывать исключения ExpiredException и SignatureInvalidException.
Использование асимметричного шифрования (RS256)
Для повышения безопасности используйте алгоритм RS256 с парой ключей (приватный/публичный). Это особенно актуально в микросервисной архитектуре:
<?php
// Генерация ключей (выполняется один раз)
// openssl genrsa -out private.pem 2048
// openssl rsa -in private.pem -pubout -out public.pem
$privateKey = file_get_contents('/path/to/private.pem');
$publicKey = file_get_contents('/path/to/public.pem');
$payload = [
'user_id' => 42,
'role' => 'admin',
'exp' => time() + 7200
];
// Создание токена с приватным ключом
$jwt = JWT::encode($payload, $private