Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как работает JWT (JSON Web Token)
JWT - это стандарт для безопасной передачи информации между сторонами в виде JSON объекта. Он самоподтверждающийся и закодирован.
Структура JWT
JWT состоит из трех частей, разделенных точками:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
[Header].[Payload].[Signature]
Часть 1: Header (Заголовок)
Описывает тип токена и алгоритм подписи:
// Декодированный header
{
"alg": "HS256", // Алгоритм подписи
"typ": "JWT" // Тип токена
}
// Base64URL кодируется
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Часть 2: Payload (Полезная нагрузка)
Содержит claims (утверждения) о пользователе:
// Декодированный payload
{
"sub": "1234567890", // Subject ID пользователя
"name": "John Doe", // Имя пользователя
"iat": 1516239022, // Issued at (время создания)
"exp": 1516325422, // Expiration time (время истечения)
"iss": "example.com", // Issuer (издатель)
"role": "admin" // Кастомные данные
}
// Base64URL кодируется
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Часть 3: Signature (Подпись)
Убеждает, что токен не был изменен:
// На сервере с секретным ключом
const signature = HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secretKey
);
// Результат
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Как это работает на практике
1. Авторизация (Login)
// На фронтенде
async function login(email, password) {
const response = await fetch("/api/v1/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password })
});
const { access_token } = await response.json();
// Сохраняем токен (в localStorage или Cookie)
localStorage.setItem("token", access_token);
return access_token;
}
2. Отправка запроса с токеном
// На фронтенде
async function fetchUserProfile() {
const token = localStorage.getItem("token");
const response = await fetch("/api/v1/users/me", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
});
if (response.status === 401) {
// Токен истек или невалидный
// Нужно заново авторизоваться
logout();
}
return response.json();
}
3. Проверка на сервере
# На бэкенде (FastAPI)
import jwt
from datetime import datetime, timedelta
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
# Создание токена
def create_token(user_id: str):
payload = {
"sub": user_id,
"iat": datetime.utcnow(),
"exp": datetime.utcnow() + timedelta(hours=24)
}
token = jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
return token
# Проверка токена
def verify_token(token: str):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id = payload.get("sub")
if user_id is None:
raise ValueError("Invalid token")
return user_id
except jwt.ExpiredSignatureError:
raise ValueError("Token expired")
except jwt.InvalidTokenError:
raise ValueError("Invalid token")
Преимущества JWT
// 1. Независимость от состояния сервера
// Не нужно хранить сессии в БД
// 2. Масштабируемость
// Токен может проверить любой сервер, зная секрет
// 3. Мобильные приложения
// Удобно передавать в заголовке Authorization
// 4. CORS-дружественный
// Работает с различными доменами
// 5. Информация внутри токена
// Сразу видна информация о пользователе
Недостатки и меры безопасности
// Проблема 1: Токен видим в Base64 (не шифруется)
// Решение: используй HTTPS для передачи
// Проблема 2: Если украли токен, его нельзя отозвать
// Решение: установи короткое время жизни (15 минут)
// Проблема 3: При изменении пароля токен еще валиден
// Решение: сохраняй версию пароля в payload для проверки
// Правильное сохранение в браузере
const storeToken = (token) => {
// ✅ В httpOnly cookie (безопаснее от XSS)
// ❌ В localStorage (уязвимо для XSS)
// ❌ В sessionStorage (тоже уязвимо)
// Если используешь localStorage, добавь CSP headers
};
Refresh Token паттерн
// Два типа токенов для большей безопасности
const tokens = {
access_token: "short-lived (15 min)", // Для API запросов
refresh_token: "long-lived (7 days)" // Для получения новых access_token
};
// При истечении access_token
async function refreshAccessToken() {
const refreshToken = localStorage.getItem("refresh_token");
const response = await fetch("/api/v1/auth/refresh", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ refresh_token: refreshToken })
});
const { access_token } = await response.json();
localStorage.setItem("token", access_token);
return access_token;
}
Ключевые моменты
- JWT не шифруется, только подписывается
- Проверка подписи гарантирует, что токен не был изменен
- Всегда передавай JWT через HTTPS
- Используй httpOnly cookies для большей безопасности
- Установи разумное время истечения токена
- Реализуй refresh token механизм для безопасности