jwt — JSON Web Tokens¶
Небольшая реализация стандарта JSON Web Token (JWT) для MicroPython. JWT — это компактный, безопасный для URL контейнер для JSON-полезной нагрузки, который издатель подписывает, чтобы проверяющая сторона могла обнаружить подделку и истечение срока действия.
Этот порт для MicroPython намеренно крошечный:
Поддерживается только HS256 (HMAC с SHA-256). Алгоритмы RSA / ECDSA / EdDSA не реализованы; издатель и проверяющая сторона должны использовать общий симметричный секретный ключ.
Необязательное утверждение
exp(срок действия) учитывается. Другие зарегистрированные утверждения (nbf,iat,iss,aud,sub,jti) передаются в полезной нагрузке без изменений, но не проверяются; приложение проверяет их, если это для него важно.Ротация ключей, JWKS и обработка списка аудитории не поддерживаются.
Функции¶
- jwt.encode(payload: dict, key: bytes | str, algorithm: str = 'HS256') str¶
Кодирует payload в подписанный JWT и возвращает результирующую компактную сериализацию (
strвида"header.payload.signature", где каждый сегмент закодирован в Base64-URL).- payload
Сериализуемый в JSON словарь утверждений. Стандартные утверждения (
exp,iat,sub, …) передаются без изменений; пользовательские ключи приложения допускаются.- key
Общий секрет HMAC. Предпочтителен
bytes;strавтоматически кодируется в UTF-8.- algorithm
Должен быть
"HS256"(по умолчанию). Любое другое значение вызываетexceptions.InvalidAlgorithmError.
- jwt.decode(token: str, key: bytes | str, algorithms: list = ['HS256']) dict¶
Проверяет подпись token и (при наличии) его утверждение
expи возвращает декодированный словарь полезной нагрузки. Вызывает подклассexceptions.PyJWTErrorпри любой ошибке — вызывающая сторона обычно перехватывает базовый класс.- token
Компактная строка JWT, созданная функцией
encode()(или любым совместимым издателем).- key
Общий секрет HMAC. Должен совпадать с ключом, использованным при кодировании.
- algorithms
Список алгоритмов, которые вызывающая сторона готова принять.
HS256должен присутствовать, и заголовокalgтокена должен быть в этом списке. По умолчанию["HS256"].
Вызывает:
exceptions.InvalidAlgorithmError—HS256отсутствует в algorithms или заголовокalgтокена отличается отHS256.exceptions.InvalidTokenError— токен сформирован неверно (не разбивается на три сегмента Base64-URL или сегмент не удаётся декодировать / разобрать как JSON).exceptions.InvalidSignatureError— подпись не совпадает с пересчитанным HMAC по заголовку и полезной нагрузке.exceptions.ExpiredSignatureError— полезная нагрузка содержит утверждениеexp, значение которого меньше текущего времени Unix. Чтобы эта проверка имела смысл, должны быть установлены часы камеры; см.ntptime.settime().
Исключения¶
Все исключения вложены в атрибут модуля jwt.exceptions.
- exception exceptions.PyJWTError¶
Базовый класс для любой ошибки JWT. Перехватывайте его, если вам не нужно различать описанные ниже случаи.
- exception exceptions.InvalidTokenError¶
Токен структурно некорректен — неверное количество сегментов, сегмент, который не удаётся декодировать из Base64, или JSON, который не удаётся разобрать. Подкласс
exceptions.PyJWTError.
- exception exceptions.InvalidAlgorithmError¶
Алгоритм токена отсутствует в списке принимаемых вызывающей стороной, либо вызывающая сторона запросила алгоритм, отличный от
HS256. Подклассexceptions.PyJWTError.
- exception exceptions.InvalidSignatureError¶
Подпись токена не совпадает с HMAC, вычисленным по заголовку и полезной нагрузке с использованием предоставленного ключа. Подкласс
exceptions.PyJWTError.
- exception exceptions.ExpiredSignatureError¶
Утверждение
expтокена находится в прошлом. Подклассexceptions.PyJWTError. Чтобы эта проверка имела смысл, должно быть установлено реальное время камеры (черезntptime.settime()).
Пример¶
Цикл выпуска/проверки с симметричным секретом:
import jwt
import time
SECRET = b"keep-this-out-of-source-control"
payload = {
"sub": "kitchen-cam",
"role": "admin",
"exp": time.time() + 3600, # 1 hour from now
}
token = jwt.encode(payload, SECRET)
print("token:", token)
try:
claims = jwt.decode(token, SECRET)
except jwt.exceptions.PyJWTError as e:
print("rejected:", type(e).__name__)
else:
print("subject:", claims["sub"])
Для подписи и проверки используется один и тот же секрет, поэтому проверяющая сторона должна располагать ключом, использованным издателем. Для сервисов, где издателем является камера (выдающая токены сопряжённому телефону), храните секрет в файловой системе камеры и обращайтесь с ним как с любыми другими долгоживущими учётными данными — см. Эксплуатация: ключи, истечение срока и устранение неполадок.