FastAPI для начинающих: API с базой данных и тестамиПользователи и доступВход и JWT access token

Вход и JWT access token

Уроки курсаВход и JWT access token

Чтение payload: кодирование не подтверждает подлинность

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

Вот локальная функция для просмотра payload собственного токена:

import base64
import json

def inspect_payload(token):
    encoded = token.split(".")[1]
    padded = encoded + "=" * (-len(encoded) % 4)
    return json.loads(base64.urlsafe_b64decode(padded))

В частях JWT завершающие символы = из Base64url опускаются. Формула (-len(encoded) % 4) вычисляет, сколько нужно дописать для декодера Python. Сам Base64url допускает строки с =.

Возьмите свежий токен из успешного ответа /api/auth/login и вызовите inspect_payload(token). В словаре будет sub из 64 шестнадцатеричных символов — значение User.token_subject — и числовой exp. Его конкретное значение зависит от времени выпуска токена: в нашей функции это примерно 30 минут после выпуска, а не фиксированная дата.

sub — это token_subject пользователя, exp — Unix timestamp момента истечения. Ни пароль, ни его хеш, ни SECRET_KEY туда не попали — именно потому, что payload читается без ключа.

Важно понять, что именно здесь происходит: вы просто декодируете строку. Это не аутентификация. Подтвердить, что токен не был подменён или изменён, можно только через подпись — третью часть JWT. Подпись создаётся с помощью SECRET_KEY и алгоритма HS256; проверить её можно только тем же ключом. Если атакующий изменит sub в payload и пересчитает Base64url, подпись перестанет совпадать — но только при условии, что сервер действительно её проверяет.

Поэтому правило простое: всё, что нельзя показывать клиенту открытым текстом, не помещают в payload JWT.