JWT
JWT (JSON Web Token) — это открытый стандарт (RFC 7519) для создания токенов доступа, которые позволяют безопасно передавать данные между сторонами в формате JSON. Токен состоит из трех частей:
-
заголовок
header— указывает алгоритм подписи, -
данные
payload— передает информацию, -
подпись
signature— защищает токен от подделки.
JWT не шифрует данные. Их можно прочитать, но нельзя изменить без секретного ключа.
Варианты использования
-
Авторизация без сессий. Пользователь остается авторизованным, пока токен действителен.
-
Защищенные запросы к API. Сервер проверяет подпись токена.
-
Обмен данными между сервисами. Например, обмен между сайтом и мобильным приложением.
Создать токен
Чтобы создать JWT-токен, используйте класс Bitrix\Main\Web\JWT.
use Bitrix\Main\Web\JWT;
$secret = 'ваш-секретный-ключ'; // Храните его в безопасности
$payload = [
'user_id' => 123, // ID пользователя
'name' => 'Иван', // Дополнительные данные
];
$jwt = JWT::encode($payload, $secret); // Метод encode создает токен с алгоритмом HS256 по умолчанию
// Или с другим алгоритмом, например RS256
// $jwt = JWT::encode($payload, $privateKey, 'RS256');
-
Ключ
$secretдолжен быть длинным и содержать случайные символы. -
В
payloadможно передавать любые данные. -
По умолчанию используется алгоритм
HS256.
Ограничить время действия токена
Чтобы ограничить время действия токена, добавьте в payload параметры:
-
iat— время создания, -
exp— срок действия, -
nbf— время начала работы.
use Bitrix\Main\Web\JWT;
$secret = 'секретный-ключ';
$payload = [
'user_id' => 123,
'name' => 'Иван',
'iat' => time(), // Токен создастся сейчас
'exp' => time() + 3600, // Истечет через 1 час
'nbf' => time() + 300, // Станет активен через 5 минут
];
$jwt = JWT::encode($payload, $secret);
Учесть рассинхронизацию времени
В распределенных системах часы серверов и клиентов могут расходиться. Параметр leeway задает допустимое отклонение в секундах.
JWT::$leeway = 30; // Разрешено отклонение на 30 секунд
$payload = ['user_id' => 42, 'exp' => time() + 3600]; // Токен истечет через 1 час
$token = JWT::encode($payload, 'secret');
$decoded = JWT::decode($token, 'secret', ['HS256']); // Учитывает параметр leeway
Проверить токен
Чтобы проверить токен и получить данные используйте метод decode.
use Bitrix\Main\Web\JWT;
$secret = 'ваш-секретный-ключ';
$jwt = 'токен-полученный-от-клиента';
try {
$payload = JWT::decode($jwt, $secret, ['HS256']);
// Токен верный, работаем с данными:
echo 'Пользователь: ' . $payload->name;
} catch (Exception $e) {
// Токен не прошёл проверку
echo 'Ошибка: ' . $e->getMessage();
}
Всегда указывайте алгоритм в параметрах метода, например, ['HS256']. Иначе система может принять токен, подписанный слабым алгоритмом.
Возможные ошибки
-
Неверная подпись — ключ не совпадает.
-
Токен просрочен — если указан параметр
exp. -
Токен еще не активен — если указан параметр
nbf.
Поддерживаемые алгоритмы подписи
Класс Bitrix\Main\Web\JWT поддерживает алгоритмы:
| Алгоритм | Тип подписи | Использует |
|---|---|---|
| HS256 | HMAC + SHA-256 | Симметричный ключ |
| HS384 | HMAC + SHA-384 | Симметричный ключ |
| HS512 | HMAC + SHA-512 | Симметричный ключ |
| RS256 | RSA + SHA-256 | Пару ключей |
| RS384 | RSA + SHA-384 | Пару ключей |
| RS512 | RSA + SHA-512 | Пару ключей |
| ES256 | ECDSA + SHA-256 | Пару ключей |
-
Алгоритмы HS* проще в использовании, так как они используют один секретный ключ.
-
Алгоритмы RS*/ES* — безопаснее, но требуют два ключа: публичный и приватный.
Рекомендации по безопасности
-
Не храните важные данные в JWT — токен можно раскодировать. Важные данные лучше хранить на сервере, а в токене передавать только ссылки или идентификаторы.
-
Храните ключ надежно — токены можно подделать при наличии ключа.
-
Используйте HTTPS — зашифрованное соединение защитит от перехвата токена.
-
Выбирайте надежный алгоритм — HS256 для простых случаев или RS256 для повышенной безопасности.