← Назад к вопросам

Какую проблему решает JWT?

2.0 Middle🔥 191 комментариев
#Безопасность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Проблема, которую решает JWT

JWT решает несколько критических проблем в современной разработке веб-приложений, особенно актуальных для масштабируемых систем.

1. Проблема: Session State в масштабируемых системах

До JWT: Традиционная аутентификация использовала session-ориентированный подход. Сервер хранил данные сессии в памяти или БД:

# Старый подход с сессиями
from flask import Flask, session

app = Flask(__name__)
app.secret_key = 'secret'

@app.route('/login', methods=['POST'])
def login():
    # Проверяем учётные данные
    session['user_id'] = user.id  # Сохраняем в памяти сервера
    return {'status': 'logged_in'}

@app.route('/api/users/me')
def me():
    user_id = session.get('user_id')  # Ищем в памяти
    return {'id': user_id}

Проблемы:

  • Если за балансировщиком нагрузки несколько серверов, сессия на Server-A недоступна на Server-B
  • Нужна shared сессионная хранилище (Redis, Memcached) — дополнительные затраты
  • Нагрузка на БД/Redis при каждом запросе
  • Сложная синхронизация в микросервисной архитектуре

JWT решает: Токен содержит всю информацию и подписан. Сервер не хранит состояние.

from fastapi import FastAPI, Depends
from fastapi.security import HTTPBearer
import jwt
from datetime import datetime, timedelta, timezone

app = FastAPI()
SECRET_KEY = "secret"

def get_current_user(token: str = Depends(HTTPBearer())):
    # Декодируем токен — никаких обращений к БД/Redis
    payload = jwt.decode(token.credentials, SECRET_KEY, algorithms=["HS256"])
    return payload['sub']

@app.get("/api/users/me")
def me(username: str = Depends(get_current_user)):
    # Один декод — готово. Работает на любом сервере
    return {'username': username}

2. Проблема: CSRF атаки в традиционных куках

Проблема: Когда используются куки для хранения session ID, они автоматически отправляются браузером при каждом запросе. Это создаёт уязвимость CSRF (Cross-Site Request Forgery):

<!-- Вредоносный сайт может сделать запрос от вашего имени -->
<img src="https://yourbank.com/transfer?amount=1000&to=attacker" />

JWT решает: Токен явно передаётся в заголовке Authorization и не отправляется автоматически:

// Токен передаётся только когда мы его явно добавим
fetch('/api/users/me', {
    headers: {
        'Authorization': `Bearer ${token}`  // Явное действие
    }
});

Вредоносный сайт не может добавить этот заголовок из-за Same-Origin Policy.

3. Проблема: Масштабируемость в микросервисной архитектуре

Сценарий:

Апи-гейтвей → Сервис users → Сервис orders → Сервис payments

Без JWT: Каждый микросервис должен проверить сессию, что требует общего хранилища сессий:

# Сервис orders должен валидировать сессию
@app.get("/orders")
def get_orders():
    # Обращаемся к Redis для проверки
    user_id = redis.get(f"session:{session_id}")
    if not user_id:
        raise HTTPException(401)

С JWT: Каждый микросервис независимо проверяет подпись токена:

# Каждый сервис может проверить токен
@app.get("/orders")
def get_orders(token: str = Depends(get_token)):
    # Простой декод и проверка подписи
    payload = jwt.decode(token, SECRET_KEY)  # Быстро, локально
    user_id = payload['sub']

4. Проблема: Мобильные приложения и API

Проблема: Мобильные приложения и SPA не удобно работают с куками. Браузер управляет ними автоматически, но мобильный клиент должен сам их обрабатывать.

JWT решает: Универсальный способ для веб, мобилки, IoT устройств:

# Один протокол для всех клиентов
@app.post("/api/v1/auth/login")
def login(credentials: LoginRequest):
    token = jwt.encode({'sub': user.id, 'exp': ...}, SECRET_KEY)
    return {'access_token': token}  # Все клиенты получают одинаково

5. Проблема: Cross-Origin запросы (CORS)

Проблема: Куки работают по правилу Same-Site, что затрудняет CORS в микросервисной архитектуре.

JWT решает: Токен в заголовке работает со всеми источниками без ограничений.

6. Проблема: Выбора между локальным кешем и БД

Практический пример из моего опыта: Я оптимизировал аутентификацию в системе с 100+ микросервисами:

# ДО: каждый запрос → Redis
# Задержка: ~5-10ms на запрос
# Нагрузка: ~1000 req/sec → 10,000 операций Redis/sec

# ПОСЛЕ: JWT с локальной проверкой
# Задержка: ~0.1-0.5ms
# Нагрузка: почти 0 операций в хранилище

Когда НЕ использовать JWT

Есть случаи, когда традиционные сессии лучше:

  • Когда нужно мгновенно отозвать доступ (JWT живёт до expiration)
  • Когда требуется сложное управление правами в реальном времени
  • Когда токены становятся очень большими (много claims)

Для решения используют refresh tokens с коротким lifetime и чёрные списки (blacklist) в Redis для отзыва.

Вывод

JWT решает фундаментальную проблему stateless масштабируемой аутентификации. Это критично для:

  • Распределённых систем
  • Микросервисной архитектуры
  • Мобильных приложений
  • API-first разработки

В своих проектах я использовал JWT с refresh tokens и логированием попыток подделок для оптимального баланса между безопасностью и производительностью.

Какую проблему решает JWT? | PrepBro