Files
fastapi/docs/ru/docs/tutorial/security/first-steps.md
T
286344571f 🌐 Update translations for ru (update-outdated) (#16210)
Co-authored-by: pr-submit[bot] <pr-submit[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: pr-push[bot] <pr-push[bot]@users.noreply.github.com>
2026-08-19 10:57:37 +02:00

14 KiB
Raw Blame History

Безопасность — первые шаги

Представим, что у вас есть бэкенд API на некотором домене.

И у вас есть фронтенд на другом домене или на другом пути того же домена (или в мобильном приложении).

И вы хотите, чтобы фронтенд мог аутентифицироваться на бэкенде, используя имя пользователя и пароль.

Мы можем использовать OAuth2, чтобы построить это с FastAPI.

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

Воспользуемся инструментами, предоставленными FastAPI, чтобы работать с безопасностью.

Как это выглядит

Сначала просто воспользуемся кодом и посмотрим, как он работает, а затем вернемся и разберемся, что происходит.

Создание main.py

Скопируйте пример в файл main.py:

{* ../../docs_src/security/tutorial001_an_py310.py *}

Запуск

/// note | Примечание

Пакет python-multipart автоматически устанавливается вместе с FastAPI, когда вы запускаете команду uv add "fastapi[standard]".

Однако, если вы используете команду uv add fastapi, пакет python-multipart по умолчанию не включается.

Чтобы установить его вручную, добавьте его в ваш проект с помощью:

$ uv add python-multipart

Это связано с тем, что OAuth2 использует «данные формы» для отправки username и password.

///

Запустите пример командой:

$ uv run fastapi dev

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Проверка

Перейдите к интерактивной документации по адресу: http://127.0.0.1:8000/docs.

Вы увидите примерно следующее:

/// tip | Кнопка авторизации!

У вас уже появилась новая кнопка «Authorize».

А у вашей операции пути в правом верхнем углу есть маленький замочек, на который можно нажать.

///

Если нажать на нее, появится небольшая форма авторизации, в которую нужно ввести username и password (и другие необязательные поля):

/// note | Примечание

Неважно, что вы введете в форму — пока это не будет работать. Но мы скоро до этого дойдем.

///

Конечно, это не фронтенд для конечных пользователей, но это отличный автоматический инструмент для интерактивного документирования всего вашего API.

Им может пользоваться команда фронтенда (которой можете быть и вы сами).

Им могут пользоваться сторонние приложения и системы.

И им также можете пользоваться вы сами, чтобы отлаживать, проверять и тестировать то же самое приложение.

«password flow» (аутентификация по паролю)

Теперь давайте немного вернемся и разберемся, что это все такое.

«password flow» — это один из способов («flows»), определенных в OAuth2, для обеспечения безопасности и аутентификации.

OAuth2 был спроектирован так, чтобы бэкенд или API были независимы от сервера, который аутентифицирует пользователя.

Но в нашем случае одно и то же приложение FastAPI будет работать и с API, и с аутентификацией.

Итак, рассмотрим это с упрощенной точки зрения:

  • Пользователь вводит на фронтенде username и password и нажимает Enter.
  • Фронтенд (работающий в браузере пользователя) отправляет эти username и password на конкретный URL в нашем API (объявленный с tokenUrl="token").
  • API проверяет этот username и password и отвечает «токеном» (мы еще ничего из этого не реализовали).
    • «Токен» — это просто строка с некоторым содержимым, которое мы сможем позже использовать для проверки этого пользователя.
    • Обычно у токена установлен срок действия: он истекает через некоторое время.
      • Поэтому пользователю придется снова войти в систему в какой‑то момент.
      • И если токен украдут, риск меньше: это не постоянный ключ, который будет работать вечно (в большинстве случаев).
  • Фронтенд временно где‑то хранит этот токен.
  • Пользователь кликает во фронтенде, чтобы перейти в другой раздел веб‑приложения.
  • Фронтенду нужно получить дополнительные данные из API.
    • Но для этого для конкретной конечной точки нужна аутентификация.
    • Поэтому, чтобы аутентифицироваться в нашем API, он отправляет HTTP-заголовок Authorization со значением Bearer плюс сам токен.
    • Если токен содержит foobar, то содержимое заголовка Authorization будет: Bearer foobar.

Класс OAuth2PasswordBearer в FastAPI

FastAPI предоставляет несколько средств на разных уровнях абстракции для реализации этих функций безопасности.

В этом примере мы будем использовать OAuth2, с потоком Password, используя токен Bearer. Для этого мы используем класс OAuth2PasswordBearer.

/// note | Примечание

Токен «bearer» — не единственный вариант.

Но для нашего случая он — лучший.

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

В этом случае FastAPI также предоставляет инструменты, чтобы его реализовать.

///

При создании экземпляра класса OAuth2PasswordBearer мы передаем параметр tokenUrl. Этот параметр содержит URL, который клиент (фронтенд, работающий в браузере пользователя) будет использовать для отправки username и password, чтобы получить токен.

{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}

/// tip | Подсказка

Здесь tokenUrl="token" ссылается на относительный URL token, который мы еще не создали. Поскольку это относительный URL, он эквивалентен ./token.

Поскольку мы используем относительный URL, если ваш API расположен по адресу https://example.com/, то он будет ссылаться на https://example.com/token. А если ваш API расположен по адресу https://example.com/api/v1/, то он будет ссылаться на https://example.com/api/v1/token.

Использование относительного URL важно для того, чтобы ваше приложение продолжало работать даже в таком продвинутом случае, как За прокси-сервером.

///

Этот параметр не создает конечную точку / операцию пути, а объявляет, что URL /token — это тот, который клиент должен использовать для получения токена. Эта информация используется в OpenAPI, а затем в интерактивных системах документации по API.

Скоро мы также создадим и саму операцию пути.

/// note | Примечание

Если вы очень строгий «питонист», вам может не понравиться стиль имени параметра tokenUrl вместо token_url.

Это потому, что используется то же имя, что и в спецификации OpenAPI. Так, если вам нужно разобраться подробнее в какой‑то из этих схем безопасности, вы можете просто скопировать и вставить это имя, чтобы найти больше информации.

///

Переменная oauth2_scheme — это экземпляр OAuth2PasswordBearer, но она также «вызываемая».

Ее можно вызвать так:

oauth2_scheme(some, parameters)

Поэтому ее можно использовать вместе с Depends.

Использование

Теперь вы можете передать oauth2_scheme как зависимость с Depends.

{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}

Эта зависимость предоставит str, который будет присвоен параметру token функции-обработчика пути.

FastAPI будет знать, что может использовать эту зависимость для определения «схемы безопасности» в схеме OpenAPI (и в автоматической документации по API).

/// note | Технические детали

FastAPI будет знать, что может использовать класс OAuth2PasswordBearer (объявленный в зависимости) для определения схемы безопасности в OpenAPI, потому что он наследуется от fastapi.security.oauth2.OAuth2, который, в свою очередь, наследуется от fastapi.security.base.SecurityBase.

Все утилиты безопасности, интегрируемые с OpenAPI (и автоматической документацией по API), наследуются от SecurityBase, — так FastAPI понимает, как интегрировать их в OpenAPI.

///

Что он делает

Он будет искать в HTTP-запросе HTTP-заголовок Authorization, проверять, что его значение — это Bearer плюс некоторый токен, и вернет токен как str.

Если HTTP-заголовок Authorization отсутствует или его значение не содержит токен Bearer , он сразу ответит ошибкой со статус-кодом 401 (UNAUTHORIZED).

Вам даже не нужно проверять наличие токена, чтобы вернуть ошибку. Вы можете быть уверены: если ваша функция была выполнена, в этом токене будет str.

Это уже можно попробовать в интерактивной документации:

Мы пока не проверяем валидность токена, но для начала это уже неплохо.

Резюме

Таким образом, всего за 3–4 дополнительные строки у вас уже есть некая примитивная форма защиты.