Ответ
Аутентификация с использованием JWT (JSON Web Token) — это stateless-процесс, основанный на обмене подписанными токенами. Жизненный цикл токена включает генерацию, использование и валидацию.
Процесс аутентификации:
- Запрос на аутентификацию. Клиент отправляет свои учетные данные (например, логин и пароль) на специальный эндпоинт сервера (например,
/api/login). - Валидация и генерация токена. Сервер проверяет учетные данные. В случае успеха он создает JWT, который состоит из трех частей: заголовка (
header), полезной нагрузки (payload) и подписи (signature).- В
payloadобычно включают идентификатор пользователя (subилиuser_id), роли (roles) и время истечения срока действия (exp). - Сервер подписывает токен секретным ключом (для симметричного шифрования HS256) или приватным ключом ( для асимметричного RS256).
- В
- Передача токена клиенту. Сервер возвращает сгенерированный JWT клиенту в теле ответа.
- Использование токена. Клиент сохраняет токен (например, в
localStorageили в безопасныхHttpOnlycookie) и прикрепляет его к каждому последующему запросу к защищенным ресурсам в заголовкеAuthorization.Authorization: Bearer <your_jwt_token> - Валидация на сервере. При каждом запросе сервер (или API-шлюз) извлекает токен из заголовка, проверяет его подпись с помощью своего секретного ключа и валидность
payload(например, не истек ли срок действияexp). Если все в порядке, запрос обрабатывается.
Пример на Python (PyJWT):
import jwt
from datetime import datetime, timedelta, timezone
# Секретный ключ, должен храниться в безопасности
SECRET_KEY = "your-super-secret-key"
# 1. Генерация токена после успешной аутентификации
payload = {
"sub": 12345, # Идентификатор пользователя
"exp": datetime.now(timezone.utc) + timedelta(hours=1), # Срок жизни - 1 час
"iat": datetime.now(timezone.utc) # Время создания
}
token = jwt.encode(payload, SECRET_KEY, algorithm="HS256")
# 2. Проверка токена при каждом запросе
try:
decoded_payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
print("Токен валиден. User ID:", decoded_payload['sub'])
except jwt.ExpiredSignatureError:
print("Ошибка: срок действия токена истек.")
except jwt.InvalidTokenError:
print("Ошибка: невалидный токен.")
Ключевые аспекты безопасности:
- HTTPS обязателен, чтобы предотвратить перехват токена.
- Не храните чувствительные данные в
payload, так как он легко декодируется (Base64). - Используйте короткий срок жизни токенов (
exp) и реализуйте механизм их обновления (refresh tokens).