JWT: разобрать header и payload в Python

Категория: Python · Язык: Python · Обновлено:

JWT состоит из трёх частей: header, payload и signature, разделённых точками. Первые две части кодируются Base64URL и не шифруются: их можно прочитать без ключа, поэтому не помещайте в payload секреты и не доверяйте claims до проверки подписи.

Прочитать payload без проверки подписи

Python
import base64
import json

token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsImV4cCI6MTkwMDAwMDAwMH0.signature"
header_part, payload_part, signature_part = token.split(".")

def decode_part(part):
    padded = part + "=" * (-len(part) % 4)
    return json.loads(base64.urlsafe_b64decode(padded))

payload = decode_part(payload_part)
print(payload["sub"])  # 42

Функция лишь декодирует JSON. Она не проверяет криптографическую подпись, срок действия или issuer.

Правильный порядок обработки

  1. Получить токен из доверенного канала передачи.

  2. Проверить подпись библиотекой и ожидаемым алгоритмом.

  3. Проверить exp, iss, aud и другие обязательные claims.

  4. Только после этого использовать sub и роли для авторизации.

Часть

Содержимое

Header

Алгоритм подписи и тип токена

Payload

Claims: субъект, срок действия и дополнительные поля

Signature

Проверяемая подпись, подтверждающая целостность

Зашифрован ли JWT?

Обычный JWS JWT подписан, но его header и payload читаются. Зашифрованный формат JWE имеет другую структуру и требует отдельной поддержки.

Почему Base64URL отличается от Base64?

Base64URL использует - и _ вместо + и /, а завершающие = часто опускаются. При декодировании добавьте padding, как в примере.