Урок по треку Python для веба: Django и FastAPI 8 мин

Аутентификация и права в Python-бэкенде: сессии, JWT, пароли

Сессии и токены, JWT и refresh, OAuth2, хранение паролей, RBAC и проверка доступа к объекту.

Аутентификация отвечает на вопрос «кто это», авторизация на вопрос «что ему можно». Путать их на собесе нельзя, как и хранить пароли в MD5. Ниже то, что спрашивают от junior до senior.

Хранение паролей

Пароль никогда не хранят в открытом виде и не шифруют обратимо. Хранят медленный хеш с солью:

  • Django по умолчанию использует PBKDF2 с SHA256 и сотнями тысяч итераций, поддерживает Argon2 и bcrypt через PASSWORD_HASHERS.
  • В FastAPI-проектах берут argon2-cffi, bcrypt или pwdlib.
  • MD5 и SHA-256 без растяжения не подходят: они быстрые, и видеокарта перебирает миллиарды вариантов в секунду.

Соль уникальна для каждого пароля и хранится рядом с хешем, она убивает радужные таблицы и одинаковые хеши у одинаковых паролей.

Сессии

После логина сервер создаёт запись сессии (в БД, Redis или подписанной cookie) и отдаёт браузеру cookie с id сессии. На каждый запрос сервер находит сессию и пользователя.

  • Плюсы: мгновенный выход и отзыв (удалили сессию), сервер всё контролирует.
  • Cookie ставят с флагами HttpOnly (недоступна JS), Secure (только HTTPS), SameSite=Lax (защита от CSRF).
  • Для запросов, меняющих данные, нужна защита от CSRF (в Django CsrfViewMiddleware).

Токены и JWT

JWT это подписанный токен из трёх частей header.payload.signature в base64url. Payload не зашифрован, его может прочитать кто угодно; подпись гарантирует, что содержимое не меняли.

payload = {'sub': '42', 'exp': now + 15 * 60, 'iat': now, 'type': 'access'}
token = jwt.encode(payload, SECRET, algorithm='HS256')
data = jwt.decode(token, SECRET, algorithms=['HS256'])   # проверит подпись и exp
  • Короткий access (5-15 минут) в заголовке Authorization: Bearer ... и долгий refresh для получения новых access. Refresh хранят безопаснее (httpOnly cookie) и ротируют: каждый обмен выдаёт новый refresh, а старый становится недействительным.
  • Отозвать JWT до истечения нельзя без серверного состояния: нужен denylist или версия токенов у пользователя.
  • При проверке явно задают допустимые алгоритмы, иначе возможны атаки с alg: none или подменой алгоритма.
  • В payload не кладут секреты и персональные данные.

OAuth 2.0 и OpenID Connect

OAuth 2.0 это протокол делегирования доступа: приложение получает токен на действия от имени пользователя у сервера авторизации (Яндекс ID, VK ID, Google). Для входа «через Яндекс» используется OpenID Connect поверх OAuth 2.0 с ID-токеном. Для браузерных и мобильных клиентов стандартом стал Authorization Code flow с PKCE.

Авторизация

  • RBAC: роли с наборами разрешений (admin, manager, viewer).
  • Проверка на уровне объекта: «редактировать можно только свой заказ» или «только в своей организации». Её отсутствие называется IDOR (небезопасная прямая ссылка на объект) и стабильно в топе уязвимостей.
  • Проверять права нужно на сервере для каждого запроса, а не прятать кнопки во фронтенде.

Частые ошибки

  • MD5, SHA1 или «свой» хеш для паролей, отсутствие соли.
  • Сравнение токенов и подписей через == вместо hmac.compare_digest (утечка по времени).
  • JWT без exp, долгоживущий access, хранение токена в localStorage без понимания рисков XSS.
  • Проверка только «пользователь вошёл» без проверки владельца объекта.
  • Разные сообщения «нет такого email» и «неверный пароль», которые позволяют перебрать пользователей.
  • Нет ограничения попыток входа.

Что спросят на собесе

  • Чем аутентификация отличается от авторизации.
  • Как правильно хранить пароли и почему не MD5.
  • Сессии или JWT: плюсы и минусы, как отозвать JWT, зачем refresh.
  • Что такое OAuth 2.0 и чем он отличается от OpenID Connect.
  • Что такое IDOR и как построить проверку прав на уровне объектов.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.