Ответ
JWT (JSON Web Token) — это компактный, URL-безопасный способ представления утверждений (claims), которые должны быть переданы между двумя сторонами. Он часто используется для аутентификации и обмена информацией в веб-приложениях и API.
Структура токена: JWT состоит из трёх частей, разделённых точками и закодированных в Base64Url:
- Header (Заголовок): Содержит метаданные — тип токена (
typ: "JWT") и алгоритм подписи (alg, например,HS256илиRS256). - Payload (Полезная нагрузка): Содержит утверждения (claims) — данные о пользователе (например,
user_id,email) и служебную информацию (время истеченияexp, время выдачиiat). - 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).
Ответ 18+ 🔞
А, JWT! Ну, это ж классика, ебать мои старые костыли. Все его используют, а половина нихуя не понимает, как он внутри работает. Сейчас разжуем.
Представь себе бутерброд, но из трёх кусков хлеба, разделённых точками. Первый кусок — это заголовок (Header). Там написано, что это JWT и какой алгоритм подписи использовали, типа HS256. Всё это закодировано в Base64, так что любой желающий может это прочитать — это не секрет.
Второй кусок — это полезная нагрузка (Payload). Вот тут уже интереснее. Ты туда можешь запихнуть что угодно про пользователя: его id, email, роль. И ещё служебную хуйню вроде времени создания (iat) и срока годности (exp). И да, это тоже в открытом виде, просто закодированное. Так что если ты туда пароль запишешь — ты просто пидарас шерстяной, чувак. Все увидят.
А третий кусок — это подпись (Signature). Вот это уже серьёзно. Берут первые два куска (заголовок и нагрузку), склеивают, и этот винегрет шифруют с помощью секретного ключа. Если кто-то попробует в нагрузке role: 'user' поменять на role: 'god', то подпись уже не сойдётся, и токен станет невалидным. Доверия ебать ноль к такому токену.
Вот смотри, как на 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";
А потом на другом конце API ты этот токен проверяешь. Если всё ок — пускаешь в систему. Если нет — посылаешь нахуй с ошибкой 401.
// 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: Bearer <ваш.jwt.токен>. Сервер его вытаскивает и проверяет.
Теперь про плюсы и минусы. Плюсы вроде очевидны: токен самодостаточный, серверу не надо бегать в базу или кеш за сессией каждый раз. Stateless, красота.
Но минусы — это пиздопроебибна. Во-первых, его нельзя отозвать моментально. Выдал токен на час — сиди и молчи, если пользователя забанили, а токен у него ещё живой. Приходится городить чёрные списки (blacklist), а это уже state, и весь смысл теряется. Во-вторых, если секретный ключ утечёт — всё, пизда. Все токены, когда-либо выпущенные, можно считать валидными. Удивление пиздец будет у твоего начальства.
Так что запомни: храни ключ как зеницу ока, делай время жизни токена коротким (минуты, а не дни), а для долгого доступа используй связку Access Token + Refresh Token. И никогда-никогда не клади в payload то, что не должен видеть посторонний. А то будет тебе хитрая жопа с утечкой данных. Всё, лекция окончена.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶