PyJWT – работа с JWT-токенами

онлайн тренер по питону
Онлайн-тренажер Python 3 для начинающих

Теория без воды. Задачи с автоматической проверкой. Подсказки на русском языке. Работает в любом современном браузере.

начать бесплатно

Введение

JSON Web Token (JWT) стал стандартом в сфере аутентификации и авторизации API. Он позволяет передавать удостоверяющую информацию между клиентом и сервером безопасно и без необходимости сохранять сессии на стороне сервера. Одной из наиболее популярных библиотек в Python для работы с JWT является PyJWT.

PyJWT – работа с JWT-токенами упрощает создание, декодирование и проверку JWT, обеспечивая при этом поддержку различных алгоритмов шифрования. Эта статья подробно объяснит, как эффективно и безопасно использовать PyJWT в вашем проекте.

Основы JWT (JSON Web Token)

Структура JWT-токена

JWT состоит из трех частей, разделенных точками:

css
header.payload.signature
  1. Header — содержит тип токена и используемый алгоритм (например, HS256)

  2. Payload — содержит claims (требования), то есть полезные данные

  3. Signature — используется для проверки подлинности токена

Преимущества использования

  • Stateless: серверу не нужно хранить сессии

  • Компактность: легко передается в HTTP-заголовках

  • Безопасность: поддержка HMAC и RSA шифрования

Установка и настройка PyJWT

Как установить PyJWT

bash
pip install PyJWT

Импорт и начальная настройка

python
import jwt import datetime

PyJWT полностью реализует стандарт RFC 7519 и предоставляет простой интерфейс для генерации и верификации токенов.

Создание JWT-токенов с помощью PyJWT

Базовый пример

python
payload = {"user_id": 123} secret = "mysecret" token = jwt.encode(payload, secret, algorithm="HS256") print(token)

Указание срока действия и дополнительных данных

python
payload = { "user_id": 123, "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1) } token = jwt.encode(payload, secret, algorithm="HS256")

exp означает expiration — срок действия токена, который крайне рекомендуется использовать.

Проверка и декодирование JWT-токенов

Как декодировать токен

python
decoded = jwt.decode(token, secret, algorithms=["HS256"]) print(decoded)

Обработка ошибок и истечения срока действия

python
try: decoded = jwt.decode(token, secret, algorithms=["HS256"]) except jwt.ExpiredSignatureError: print("Token expired") except jwt.InvalidTokenError: print("Invalid token")

Эта обработка обеспечивает безопасность приложения и пользовательский контроль ошибок.

Алгоритмы шифрования в PyJWT

Поддерживаемые алгоритмы

  • HMAC: HS256, HS384, HS512

  • RSA: RS256, RS384, RS512

  • EC: ES256, ES384, ES512

Как выбрать нужный алгоритм

  • Для простых приложений: HS256 (секретный ключ)

  • Для распределенных систем: RS256 (публичный/приватный ключ)

Работа с секретами и ключами

Безопасность хранения ключей

Никогда не храните ключи в открытом виде. Используйте переменные окружения и менеджеры секретов.

python
import os secret = os.environ.get("JWT_SECRET")

Использование публичных и приватных ключей

Для RS256:

python
private_key = open("private.pem").read() public_key = open("public.pem").read() token = jwt.encode(payload, private_key, algorithm="RS256") decoded = jwt.decode(token, public_key, algorithms=["RS256"])

Интеграция PyJWT в веб-приложения

Пример с Flask

python
from flask import Flask, request, jsonify app = Flask(__name__) SECRET_KEY = "secret" @app.route("/login") def login(): token = jwt.encode({"user": "admin"}, SECRET_KEY, algorithm="HS256") return jsonify(token=token) @app.route("/protected") def protected(): token = request.headers.get("Authorization").split()[1] try: decoded = jwt.decode(token, SECRET_KEY, algorithms=["HS256"]) return jsonify(message="Access granted", user=decoded["user"]) except jwt.InvalidTokenError: return jsonify(error="Invalid token"), 401

Использование middleware для аутентификации

В FastAPI можно создать dependency, которая проверяет токен и возвращает пользователя.

Обработка ошибок и исключений

Типичные ошибки PyJWT

  • ExpiredSignatureError: токен истек

  • InvalidTokenError: токен некорректен

  • DecodeError: ошибка декодирования

Советы по безопасному использованию

  • Указывайте exp в каждом токене

  • Меняйте секреты регулярно

  • Никогда не используйте один и тот же ключ в тестовой и продовой среде

Сравнение PyJWT с другими библиотеками

Библиотека Особенности Минусы
PyJWT Простота, гибкость, активная поддержка Нет встроенной интеграции с веб
Authlib Расширенные возможности OAuth2 Более сложная настройка
python-jose Расширенная криптография Сложность интеграции

Расширенные возможности PyJWT

Пользовательские payload и claims

Вы можете включить дополнительные поля, такие как roles, permissions, ip, iat.

Нестандартные заголовки и поля

python
token = jwt.encode(payload, secret, algorithm="HS256", headers={"kid": "001"})

Тестирование токенов с PyJWT

Как создавать и проверять токены в тестах

python
def test_token_generation(): token = jwt.encode({"test": "data"}, "testkey", algorithm="HS256") decoded = jwt.decode(token, "testkey", algorithms=["HS256"]) assert decoded["test"] == "data"

Использование mock данных

Для изоляции тестов стоит использовать pytest и unittest.mock.

Распространенные сценарии использования

Аутентификация API пользователей

JWT часто используется для авторизации REST API в мобильных и веб-приложениях.

Сессии без состояния

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

Безопасность и рекомендации

Частые уязвимости

  • Отсутствие exp

  • Использование слабого ключа

  • Декодирование токена без проверки алгоритма

Лучшие практики использования PyJWT

  • Устанавливайте короткий срок действия

  • Используйте HTTPS

  • Проверяйте alg при декодировании

Будущее JWT и развитие PyJWT

Поддержка и активность проекта

PyJWT активно развивается и поддерживает новейшие версии Python и стандартов JWT.

Альтернативные подходы в будущем

Многие проекты рассматривают комбинирование JWT с OAuth2, OpenID Connect, а также HMAC с ротацией ключей.

Часто задаваемые вопросы (FAQ)

1. Что такое PyJWT?
PyJWT — это Python-библиотека для создания, кодирования и декодирования JWT-токенов.

2. Безопасно ли использовать JWT в продакшене?
Да, при правильной реализации и соблюдении рекомендаций.

3. Какой алгоритм лучше использовать: HS256 или RS256?
HS256 проще, RS256 безопаснее для распределенных систем.

4. Где хранить секретный ключ?
В переменных окружения или менеджерах секретов (например, AWS Secrets Manager).

5. Можно ли использовать PyJWT с FastAPI или Flask?
Да, PyJWT легко интегрируется в оба фреймворка.

6. Поддерживает ли PyJWT обновление токенов (refresh)?
Нет, но это можно реализовать вручную на уровне логики приложения.

Полный справочник по ключевым функциям и модулям библиотеки PyJWT для Python

Установка

bash
pip install PyJWT

Если требуется поддержка алгоритма RS256, установите с криптографией:

bash
pip install "PyJWT[crypto]"

Основные функции

Функция Описание
jwt.encode(payload, key, algorithm) Создает JWT-токен.
jwt.decode(token, key, algorithms=[...]) Проверяет подпись и извлекает данные.
jwt.get_unverified_header(token) Возвращает заголовки без проверки подписи.
jwt.get_unverified_claims(token) Возвращает payload без валидации.

Кодирование токена (jwt.encode)

Аргумент Описание
payload Словарь с полезной нагрузкой (данными).
key Секретный ключ или приватный ключ (если RSA).
algorithm Алгоритм шифрования (HS256, RS256, ES256 и др.).
headers (необязательно) Дополнительные заголовки токена.
python
import jwt token = jwt.encode({"user_id": 123}, "secret", algorithm="HS256") print(token)

Декодирование токена (jwt.decode)

Аргумент Описание
token JWT-строка.
key Секретный ключ (тот же, что использовался при кодировании).
algorithms Список допустимых алгоритмов.
options (необязательно) Настройки проверки (verify_exp, verify_signature и др.).
python
decoded = jwt.decode(token, "secret", algorithms=["HS256"]) print(decoded) # {'user_id': 123}

Обработка ошибок

Исключение Описание
jwt.ExpiredSignatureError Токен истёк (по claim exp).
jwt.InvalidTokenError Базовое исключение для всех ошибок.
jwt.InvalidSignatureError Неверная подпись.
jwt.DecodeError Ошибка декодирования (например, повреждённый токен).
jwt.InvalidAudienceError / InvalidIssuerError Нарушения настроек аудитории или издателя.
python
try: data = jwt.decode(token, "secret", algorithms=["HS256"]) except jwt.ExpiredSignatureError: print("Истёк срок действия токена") except jwt.InvalidTokenError: print("Недействительный токен")

Стандартные JWT claims (полезная нагрузка)

Claim Описание
iss Издатель токена.
sub Субъект (например, пользователь).
aud Аудитория (для кого предназначен токен).
exp Время истечения срока действия.
nbf Не раньше чем (not before).
iat Время выпуска (issued at).
jti Идентификатор токена (уникальный).
python
import datetime payload = { "sub": "user123", "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=30) } token = jwt.encode(payload, "secret", algorithm="HS256")

Проверка срока действия (exp)

Поведение Описание
Если в токене есть exp — PyJWT автоматически проверит его при decode.  
Можно отключить проверку: options={"verify_exp": False}  

Работа с RSA-ключами (RS256)

python
# Пример с RSA with open("private.pem") as f: private_key = f.read() with open("public.pem") as f: public_key = f.read() token = jwt.encode(payload, private_key, algorithm="RS256") data = jwt.decode(token, public_key, algorithms=["RS256"])

Получение заголовков без проверки подписи

python
jwt.get_unverified_header(token)

Совместимость

Интеграция Пример использования
FastAPI Используется в dependency-функциях для извлечения Authorization токена.
Flask Совместим с Flask-JWT, Flask-JWT-Extended.
Django Используется в JWT-аутентификации через rest_framework_simplejwt.

Заключение

PyJWT — это надежное, гибкое и простое решение для работы с JWT-токенами в Python. Он обеспечивает все ключевые функции: генерацию, верификацию, обработку ошибок и безопасность. Его использование рекомендуется для любого веб-приложения, в котором требуется аутентификация пользователей или безопасный обмен данными.

Если вы строите REST API или микросервисную архитектуру, PyJWT станет одним из главных инструментов в вашем арсенале.