]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Add Russian translation for `docs/ru/docs/tutorial/security/first-steps.md` (#10541)
authorAleksandr Andrukhov <drammtv@gmail.com>
Tue, 23 Jan 2024 14:00:11 +0000 (17:00 +0300)
committerGitHub <noreply@github.com>
Tue, 23 Jan 2024 14:00:11 +0000 (09:00 -0500)
docs/ru/docs/tutorial/security/first-steps.md [new file with mode: 0644]

diff --git a/docs/ru/docs/tutorial/security/first-steps.md b/docs/ru/docs/tutorial/security/first-steps.md
new file mode 100644 (file)
index 0000000..b70a60a
--- /dev/null
@@ -0,0 +1,232 @@
+# Безопасность - первые шаги
+
+Представим, что у вас есть свой **бэкенд** API на некотором домене.
+
+И у вас есть **фронтенд** на другом домене или на другом пути того же домена (или в мобильном приложении).
+
+И вы хотите иметь возможность аутентификации фронтенда с бэкендом, используя **имя пользователя** и **пароль**.
+
+Мы можем использовать **OAuth2** для создания такой системы с помощью **FastAPI**.
+
+Но давайте избавим вас от необходимости читать всю длинную спецификацию, чтобы найти те небольшие кусочки информации, которые вам нужны.
+
+Для работы с безопасностью воспользуемся средствами, предоставленными **FastAPI**.
+
+## Как это выглядит
+
+Давайте сначала просто воспользуемся кодом и посмотрим, как он работает, а затем детально разберём, что происходит.
+
+## Создание `main.py`
+
+Скопируйте пример в файл `main.py`:
+
+=== "Python 3.9+"
+
+    ```Python
+    {!> ../../../docs_src/security/tutorial001_an_py39.py!}
+    ```
+
+=== "Python 3.8+"
+
+    ```Python
+    {!> ../../../docs_src/security/tutorial001_an.py!}
+    ```
+
+=== "Python 3.8+ без Annotated"
+
+    !!! tip "Подсказка"
+        Предпочтительнее использовать версию с аннотацией, если это возможно.
+
+    ```Python
+    {!> ../../../docs_src/security/tutorial001.py!}
+    ```
+
+
+## Запуск
+
+!!! info "Дополнительная информация"
+    Вначале, установите библиотеку <a href="https://andrew-d.github.io/python-multipart/" class="external-link" target="_blank">`python-multipart`</a>.
+
+    А именно: `pip install python-multipart`.
+
+    Это связано с тем, что **OAuth2** использует "данные формы" для передачи `имени пользователя` и `пароля`.
+
+Запустите ваш сервер:
+
+<div class="termy">
+
+```console
+$ uvicorn main:app --reload
+
+<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+</div>
+
+## Проверка
+
+Перейдите к интерактивной документации по адресу: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+
+Вы увидите примерно следующее:
+
+<img src="/img/tutorial/security/image01.png">
+
+!!! check "Кнопка авторизации!"
+    У вас уже появилась новая кнопка "Authorize".
+
+    А у *операции пути* теперь появился маленький замочек в правом верхнем углу, на который можно нажать.
+
+При нажатии на нее появляется небольшая форма авторизации, в которую нужно ввести `имя пользователя` и `пароль` (и другие необязательные поля):
+
+<img src="/img/tutorial/security/image02.png">
+
+!!! note "Технические детали"
+    Неважно, что вы введете в форму, она пока не будет работать. Но мы к этому еще придем.
+
+Конечно, это не фронтенд для конечных пользователей, но это отличный автоматический инструмент для интерактивного документирования всех ваших API.
+
+Он может использоваться командой фронтенда (которой можете быть и вы сами).
+
+Он может быть использован сторонними приложениями и системами.
+
+Кроме того, его можно использовать самостоятельно для отладки, проверки и тестирования одного и того же приложения.
+
+## Аутентификация по паролю
+
+Теперь давайте вернемся немного назад и разберемся, что же это такое.
+
+Аутентификация по паролю является одним из способов, определенных в OAuth2, для обеспечения безопасности и аутентификации.
+
+OAuth2 был разработан для того, чтобы бэкэнд или API были независимы от сервера, который аутентифицирует пользователя.
+
+Но в нашем случае одно и то же приложение **FastAPI** будет работать с API и аутентификацией.
+
+Итак, рассмотрим его с этой упрощенной точки зрения:
+
+* Пользователь вводит на фронтенде `имя пользователя` и `пароль` и нажимает `Enter`.
+* Фронтенд (работающий в браузере пользователя) отправляет эти `имя пользователя` и `пароль` на определенный URL в нашем API (объявленный с помощью параметра `tokenUrl="token"`).
+* API проверяет эти `имя пользователя` и `пароль` и выдает в ответ "токен" (мы еще не реализовали ничего из этого).
+    * "Токен" - это просто строка с некоторым содержимым, которое мы можем использовать позже для верификации пользователя.
+    * Обычно срок действия токена истекает через некоторое время.
+        * Таким образом, пользователю придется снова войти в систему в какой-то момент времени.
+        * И если токен будет украден, то риск будет меньше, так как он не похож на постоянный ключ, который будет работать вечно (в большинстве случаев).
+* Фронтенд временно хранит этот токен в каком-то месте.
+* Пользователь щелкает мышью на фронтенде, чтобы перейти в другой раздел на фронтенде.
+* Фронтенду необходимо получить дополнительные данные из API.
+    * Но для этого необходима аутентификация для конкретной конечной точки.
+    * Поэтому для аутентификации в нашем API он посылает заголовок `Authorization` со значением `Bearer` плюс сам токен.
+    * Если токен содержит `foobar`, то содержание заголовка `Authorization` будет таким: `Bearer foobar`.
+
+## Класс `OAuth2PasswordBearer` в **FastAPI**
+
+**FastAPI** предоставляет несколько средств на разных уровнях абстракции для реализации этих функций безопасности.
+
+В данном примере мы будем использовать **OAuth2**, с аутентификацией по паролю, используя токен **Bearer**. Для этого мы используем класс `OAuth2PasswordBearer`.
+
+!!! info "Дополнительная информация"
+    Токен "bearer" - не единственный вариант, но для нашего случая он является наилучшим.
+
+    И это может быть лучшим вариантом для большинства случаев использования, если только вы не являетесь экспертом в области OAuth2 и точно знаете, почему вам лучше подходит какой-то другой вариант.
+
+    В этом случае **FastAPI** также предоставляет инструменты для его реализации.
+
+При создании экземпляра класса `OAuth2PasswordBearer` мы передаем в него параметр `tokenUrl`. Этот параметр содержит URL, который клиент (фронтенд, работающий в браузере пользователя) будет использовать для отправки `имени пользователя` и `пароля` с целью получения токена.
+
+=== "Python 3.9+"
+
+    ```Python hl_lines="8"
+    {!> ../../../docs_src/security/tutorial001_an_py39.py!}
+    ```
+
+=== "Python 3.8+"
+
+    ```Python  hl_lines="7"
+    {!> ../../../docs_src/security/tutorial001_an.py!}
+    ```
+
+=== "Python 3.8+ без Annotated"
+
+    !!! tip "Подсказка"
+        Предпочтительнее использовать версию с аннотацией, если это возможно.
+
+    ```Python hl_lines="6"
+    {!> ../../../docs_src/security/tutorial001.py!}
+    ```
+
+!!! 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 важно для того, чтобы ваше приложение продолжало работать даже в таких сложных случаях, как оно находится [за прокси-сервером](../../advanced/behind-a-proxy.md){.internal-link target=_blank}.
+
+Этот параметр не создает конечную точку / *операцию пути*, а объявляет, что URL `/token` будет таким, который клиент должен использовать для получения токена. Эта информация используется в OpenAPI, а затем в интерактивных системах документации API.
+
+Вскоре мы создадим и саму операцию пути.
+
+!!! info "Дополнительная информация"
+    Если вы очень строгий "питонист", то вам может не понравиться стиль названия параметра `tokenUrl` вместо `token_url`.
+
+    Это связано с тем, что тут используется то же имя, что и в спецификации OpenAPI. Таким образом, если вам необходимо более подробно изучить какую-либо из этих схем безопасности, вы можете просто использовать копирование/вставку, чтобы найти дополнительную информацию о ней.
+
+Переменная `oauth2_scheme` является экземпляром `OAuth2PasswordBearer`, но она также является "вызываемой".
+
+Ее можно вызвать следующим образом:
+
+```Python
+oauth2_scheme(some, parameters)
+```
+
+Поэтому ее можно использовать вместе с `Depends`.
+
+### Использование
+
+Теперь вы можете передать ваш `oauth2_scheme` в зависимость с помощью `Depends`.
+
+=== "Python 3.9+"
+
+    ```Python hl_lines="12"
+    {!> ../../../docs_src/security/tutorial001_an_py39.py!}
+    ```
+
+=== "Python 3.8+"
+
+    ```Python  hl_lines="11"
+    {!> ../../../docs_src/security/tutorial001_an.py!}
+    ```
+
+=== "Python 3.8+ без Annotated"
+
+    !!! tip "Подсказка"
+        Предпочтительнее использовать версию с аннотацией, если это возможно.
+
+    ```Python hl_lines="10"
+    {!> ../../../docs_src/security/tutorial001.py!}
+    ```
+
+Эта зависимость будет предоставлять `строку`, которая присваивается параметру `token` в *функции операции пути*.
+
+**FastAPI** будет знать, что он может использовать эту зависимость для определения "схемы безопасности" в схеме OpenAPI (и автоматической документации по API).
+
+!!! info "Технические детали"
+    **FastAPI** будет знать, что он может использовать класс `OAuth2PasswordBearer` (объявленный в зависимости) для определения схемы безопасности в OpenAPI, поскольку он наследуется от `fastapi.security.oauth2.OAuth2`, который, в свою очередь, наследуется от `fastapi.security.base.SecurityBase`.
+
+    Все утилиты безопасности, интегрируемые в OpenAPI (и автоматическая документация по API), наследуются от `SecurityBase`, поэтому **FastAPI** может знать, как интегрировать их в OpenAPI.
+
+## Что он делает
+
+Он будет искать в запросе заголовок `Authorization` и проверять, содержит ли он значение `Bearer` с некоторым токеном, и возвращать токен в виде `строки`.
+
+Если он не видит заголовка `Authorization` или значение не имеет токена `Bearer`, то в ответ будет выдана ошибка с кодом состояния 401 (`UNAUTHORIZED`).
+
+Для возврата ошибки даже не нужно проверять, существует ли токен. Вы можете быть уверены, что если ваша функция будет выполнилась, то в этом токене есть `строка`.
+
+Проверить это можно уже сейчас в интерактивной документации:
+
+<img src="/img/tutorial/security/image03.png">
+
+Мы пока не проверяем валидность токена, но для начала неплохо.
+
+## Резюме
+
+Таким образом, всего за 3-4 дополнительные строки вы получаете некую примитивную форму защиты.