Ответ
JSON Web Token (JWT) — это компактный, URL-безопасный способ представления утверждений (claims), которые должны быть переданы между двумя сторонами. В веб-разработке на Node.js JWT чаще всего используется как стандарт для токенов доступа в stateless-аутентификации.
Структура токена (Header.Payload.Signature):
- Header: Содержит тип токена (
typ: "JWT") и алгоритм подписи (alg, например,HS256илиRS256). - Payload: Содержит утверждения (claims) — данные о пользователе (например,
userId,role) и служебную информацию (iss— издатель,exp— срок действия). - Signature: Создается путём кодирования header и payload по алгоритму Base64Url, их объединения и подписи с использованием секретного ключа (для
HS256) или приватного ключа (дляRS256). Подпись обеспечивает целостность токена.
Пример работы с JWT в Node.js (библиотека jsonwebtoken):
const jwt = require('jsonwebtoken');
const SECRET_KEY = process.env.JWT_SECRET; // Хранить в переменных окружения!
// 1. Создание (подписание) токена при успешном логине
function generateAccessToken(user) {
return jwt.sign(
{
userId: user.id,
role: user.role
}, // Payload
SECRET_KEY,
{ expiresIn: '15m' } // Токен действует 15 минут
);
}
// 2. Верификация и декодирование токена в middleware
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1]; // Извлечь токен из 'Bearer <token>'
if (!token) return res.sendStatus(401);
jwt.verify(token, SECRET_KEY, (err, user) => {
if (err) return res.sendStatus(403); // Токен невалиден или просрочен
req.user = user; // Добавляем данные из payload в объект запроса
next();
});
}
Важные моменты:
- JWT не зашифрован, а только закодирован и подписан. Не храните в payload конфиденциальные данные.
- Для обеспечения безопасности используйте короткое время жизни Access Token и механизм Refresh Token.
- Подпись
HS256использует один секретный ключ,RS256— пару приватный/публичный ключ, что безопаснее для распределённых систем.
Ответ 18+ 🔞
Э, слушай, давай разберем эту вашу моду, про которую все так носятся — JSON Web Token, или просто JWT. Выглядит как абракадабра из трёх кусков, разделённых точками, а на деле — просто способ сказать: «Чувак, я свой, пусти».
Из чего эта штука состоит, или «Раздевай токен, показывай claims»:
- Header (Заголовок): Тут всё просто, как три копейки. Тип —
"JWT", и алгоритм, которым эту хрень подписали (например,HS256). Всё это в Base64, чтобы не ломать глаза. - Payload (Полезная нагрузка): А вот тут самое интересное лежит. Всё, что ты туда запихнул:
userId,role, срок годности (exp). Помни, что это не зашифровано, а просто закодировано! Любой мудак может декодировать и посмотреть. Так что не пихай туда пароль бабушки или размер своего достоинства. - Signature (Подпись): Вот тут и кроется вся магия, не дающая токену превратиться в манду с ушами. Берется закодированные header и payload, склеиваются, и эта солянка подписывается секретным ключом (или приватным, если алгоритм посерьёзнее). Если кто-то попробует в payload что-то поменять — подпись не сойдётся, и токен накроется медным тазом.
Как с этим жить в Node.js (библиотека jsonwebtoken):
const jwt = require('jsonwebtoken');
const SECRET_KEY = process.env.JWT_SECRET; // Храни ключ в окружении, а не в коде, распиздяй!
// 1. Создаём токен, когда пользователь залогинился
function generateAccessToken(user) {
return jwt.sign(
{
userId: user.id,
role: user.role
}, // Вот это всё улетит в payload
SECRET_KEY,
{ expiresIn: '15m' } // Живёт 15 минут. Не делай вечные токены — это пиздец как небезопасно.
);
}
// 2. Проверяем каждый раз, когда чувак стучится к нам
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
// Вытаскиваем токен из заголовка 'Bearer <token>'. Если его нет — сразу 401, иди нахуй.
const token = authHeader && authHeader.split(' ')[1];
if (!token) return res.sendStatus(401);
// А вот тут сама верификация. Если токен просрочен или подпись кривая — получишь 403.
jwt.verify(token, SECRET_KEY, (err, user) => {
if (err) return res.sendStatus(403);
req.user = user; // Если всё ок — кладём расшифрованные данные в запрос
next();
});
}
На что смотреть, чтобы не обосраться:
- Повторю, как мантру: JWT НЕ ШИФРУЕТ. Он только кодирует и подписывает. Все данные в payload — на виду. Доверия ебать ноль к тому, что там лежит, если ты сам это не положил и не подписал.
- Access Token должен жить недолго (минуты). Для долгой сессии используй связку Access + Refresh Token, иначе любой, кто украл токен, будет гулять по твоему API, пока тот не протухнет.
HS256— симметричная подпись, один ключ и для создания, и для проверки. Просто, но если ключ утечёт — пидарас шерстяной, всем пизда.RS256(публичный/приватный ключ) — надёжнее для микросервисов.