Browse Source

Apply changes from latest PRs: 13917 and 14099

pull/14123/head
Yurii Motov 10 months ago
parent
commit
bb6ee78a0b
  1. 49
      docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
  2. 68
      docs/ru/docs/tutorial/security/oauth2-jwt.md

49
docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md

@ -35,7 +35,7 @@ FastAPI поддерживает зависимости, которые выпо
{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
Код, следующий за оператором `yield`, выполняется после создания ответа, но до его отправки:
Код, следующий за оператором `yield`, выполняется после ответа:
{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
@ -95,9 +95,11 @@ FastAPI поддерживает зависимости, которые выпо
## Зависимости с `yield` и `HTTPException` { #dependencies-with-yield-and-httpexception }
Вы видели, что можно использовать зависимости с `yield` и иметь блоки `try`, которые отлавливают исключения.
Вы видели, что можно использовать зависимости с `yield` и иметь блоки `try`, которые пытаются выполнить некоторый код, а затем запускают код выхода в `finally`.
Точно так же можно <abbr title="«raise» дословно - «поднять», но «вызвать», «сгенерировать» или «выбросить» употребляется чаще">вызвать</abbr> `HTTPException` или что-то подобное в коде выхода, после `yield`.
Также вы можете использовать `except`, чтобы поймать вызванное исключение и что-то с ним сделать.
Например, вы можете <abbr title="«raise» дословно - «поднять», но «вызвать», «сгенерировать» или «выбросить» употребляется чаще">вызвать</abbr> другое исключение, например `HTTPException`.
/// tip | Подсказка
@ -109,7 +111,7 @@ FastAPI поддерживает зависимости, которые выпо
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
Альтернативой для отлавливания исключений (и, возможно, для вызова другого `HTTPException`) может быть создание [Пользовательского обработчика исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
Если вы хотите перехватывать исключения и формировать на их основе пользовательский ответ, создайте [Пользовательский обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
## Зависимости с `yield` и `except` { #dependencies-with-yield-and-except }
@ -178,48 +180,15 @@ participant tasks as Background tasks
/// tip | Подсказка
На этой диаграмме показан `HTTPException`, но вы также можете вызвать любое другое исключение, которое ловите в зависимости с `yield` или с [Пользовательским обработчиком исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
Если вы вызываете какое-либо исключение, оно будет передано зависимостям с `yield`, включая `HTTPException`. В большинстве случаев вы захотите повторно вызвать то же самое исключение или новое из зависимости с `yield`, чтобы убедиться, что оно корректно обработано.
Если вы вызовете какое-либо исключение в коде из *функции-обработчика пути*, оно будет передано зависимостям с `yield`, включая `HTTPException`. В большинстве случаев вы захотите повторно вызвать то же самое исключение или новое из зависимости с `yield`, чтобы убедиться, что оно корректно обработано.
///
## Зависимости с `yield`, `HTTPException`, `except` и фоновыми задачами { #dependencies-with-yield-httpexception-except-and-background-tasks }
/// warning | Внимание
Скорее всего, вам не нужны эти технические подробности, вы можете пропустить этот раздел и продолжить ниже.
Эти подробности полезны в основном, если вы использовали версию FastAPI до 0.106.0 и использовали ресурсы из зависимостей с `yield` в фоновых задачах.
///
### Зависимости с `yield` и `except`, технические детали { #dependencies-with-yield-and-except-technical-details }
До FastAPI 0.110.0, если вы использовали зависимость с `yield`, затем ловили исключение с `except` в этой зависимости и не вызывали исключение снова, исключение автоматически пробрасывалось/перенаправлялось обработчикам исключений или внутреннему обработчику ошибок сервера.
В версии 0.110.0 это было изменено, чтобы исправить неконтролируемое потребление памяти от перенаправленных исключений без обработчика (внутренние ошибки сервера) и сделать поведение согласованным с поведением обычного Python-кода.
### Фоновые задачи и зависимости с `yield`, технические детали { #background-tasks-and-dependencies-with-yield-technical-details }
До FastAPI 0.106.0 вызывать исключения после `yield` было невозможно: код выхода в зависимостях с `yield` выполнялся *после* отправки ответа, поэтому [Обработчики исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} уже отрабатывали.
Так было задумано главным образом для того, чтобы позволить использовать те же объекты, «отданные» зависимостями, внутри фоновых задач, поскольку код выхода выполнялся после завершения фоновых задач.
Тем не менее, так как это означало ожидание доставки ответа по сети при одновременном ненужном удержании ресурса в зависимости с `yield` (например, соединения с базой данных), это было изменено в FastAPI 0.106.0.
/// tip | Подсказка
Кроме того, фоновая задача обычно представляет собой независимый набор логики, который следует обрабатывать отдельно, со своими собственными ресурсами (например, со своим подключением к базе данных).
Таким образом, код, скорее всего, получится чище.
///
Если вы полагались на это поведение, теперь вам следует создавать ресурсы для фоновых задач внутри самой фоновой задачи и использовать внутри только данные, которые не зависят от ресурсов зависимостей с `yield`.
Например, вместо того чтобы использовать ту же сессию базы данных, вы создадите новую сессию базы данных внутри фоновой задачи и получите объекты из базы данных с помощью этой новой сессии. А затем, вместо того чтобы передавать объект из базы данных в качестве параметра функции фоновой задачи, вы передадите идентификатор этого объекта, а затем снова получите объект внутри функции фоновой задачи.
Зависимости с `yield` со временем эволюционировали, чтобы покрыть разные сценарии и исправить некоторые проблемы.
Если вы хотите посмотреть, что менялось в разных версиях FastAPI, вы можете прочитать об этом подробнее в продвинутом руководстве: [Продвинутые зависимости — зависимости с `yield`, `HTTPException`, `except` и фоновыми задачами](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}.
## Контекстные менеджеры { #context-managers }
### Что такое «контекстные менеджеры» { #what-are-context-managers }

68
docs/ru/docs/tutorial/security/oauth2-jwt.md

@ -1,12 +1,12 @@
# OAuth2 с паролем (и хешированием), Bearer с JWT-токенами
# OAuth2 с паролем (и хешированием), Bearer с JWT-токенами { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
Теперь, когда у нас определен процесс обеспечения безопасности, давайте сделаем приложение действительно безопасным, используя токены <abbr title="JSON Web Tokens">JWT</abbr> и безопасное хеширование паролей.
Теперь, когда у нас определен процесс обеспечения безопасности, давайте сделаем приложение действительно безопасным, используя токены <abbr title="JSON Web Tokens – веб‑токены JSON">JWT</abbr> и безопасное хеширование паролей.
Этот код можно реально использовать в своем приложении, сохранять хэши паролей в базе данных и т.д.
Мы продолжим разбираться, начиная с того места, на котором остановились в предыдущей главе.
## Про JWT
## Про JWT { #about-jwt }
JWT означает "JSON Web Tokens".
@ -26,7 +26,7 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4
Если вы хотите поиграть с JWT-токенами и посмотреть, как они работают, посмотрите <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a>.
## Установка `PyJWT`
## Установка `PyJWT` { #install-pyjwt }
Нам необходимо установить `pyjwt` для генерации и проверки JWT-токенов на языке Python.
@ -45,10 +45,10 @@ $ pip install pyjwt
/// info | Дополнительная информация
Если вы планируете использовать алгоритмы цифровой подписи, такие как RSA или ECDSA, вам следует установить зависимость библиотеки криптографии `pyjwt[crypto]`.
Подробнее об этом можно прочитать в <a href=«https://pyjwt.readthedocs.io/en/latest/installation.html» class=«external-link» target=«_blank»>документации по установке PyJWT</a>.
Подробнее об этом можно прочитать в <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">документации по установке PyJWT</a>.
///
## Хеширование паролей
## Хеширование паролей { #password-hashing }
"Хеширование" означает преобразование некоторого содержимого (в данном случае пароля) в последовательность байтов (просто строку), которая выглядит как тарабарщина.
@ -56,26 +56,26 @@ $ pip install pyjwt
Но преобразовать тарабарщину обратно в пароль невозможно.
### Для чего нужно хеширование паролей
### Для чего нужно хеширование паролей { #why-use-password-hashing }
Если ваша база данных будет украдена, то вор не получит пароли пользователей в открытом виде, а только их хэши.
Таким образом, вор не сможет использовать этот пароль в другой системе (поскольку многие пользователи везде используют один и тот же пароль, это было бы опасно).
## Установка `passlib`
## Установка `pwdlib` { #install-pwdlib }
PassLib - это отличный пакет Python для работы с хэшами паролей.
pwdlib — это отличный пакет Python для работы с хэшами паролей.
Он поддерживает множество безопасных алгоритмов хеширования и утилит для работы с ними.
Рекомендуемый алгоритм - "Bcrypt".
Рекомендуемый алгоритм — "Argon2".
Убедитесь, что вы создали и активировали виртуальное окружение, и затем установите PassLib вместе с Bcrypt:
Убедитесь, что вы создали [виртуальное окружение](../../virtual-environments.md){.internal-link target=_blank}, активируйте его, и затем установите pwdlib вместе с Argon2:
<div class="termy">
```console
$ pip install "passlib[bcrypt]"
$ pip install "pwdlib[argon2]"
---> 100%
```
@ -83,40 +83,40 @@ $ pip install "passlib[bcrypt]"
</div>
/// tip | Подсказка
С помощью `passlib` можно даже настроить его на чтение паролей, созданных **Django**, плагином безопасности **Flask** или многими другими библиотеками.
С помощью `pwdlib` можно даже настроить его на чтение паролей, созданных **Django**, плагином безопасности **Flask** или многими другими библиотеками.
Таким образом, вы сможете, например, совместно использовать одни и те же данные из приложения Django в базе данных с приложением FastAPI. Или постепенно мигрировать Django-приложение, используя ту же базу данных.
При этом пользователи смогут одновременно входить в систему как из приложения Django, так и из приложения **FastAPI**.
///
## Хеширование и проверка паролей
## Хеширование и проверка паролей { #hash-and-verify-the-passwords }
Импортируйте необходимые инструменты из `passlib`.
Импортируйте необходимые инструменты из `pwdlib`.
Создайте "контекст" PassLib. Именно он будет использоваться для хэширования и проверки паролей.
Создайте экземпляр PasswordHash с рекомендованными настройками — он будет использоваться для хэширования и проверки паролей.
/// tip | Подсказка
Контекст PassLib также имеет функциональность для использования различных алгоритмов хеширования, в том числе и устаревших, только для возможности их проверки и т.д.
pwdlib также поддерживает алгоритм хеширования bcrypt, но не включает устаревшие алгоритмы — для работы с устаревшими хэшами рекомендуется использовать библиотеку passlib.
Например, вы можете использовать его для чтения и проверки паролей, сгенерированных другой системой (например, Django), но хэшировать все новые пароли другим алгоритмом, например Bcrypt.
Например, вы можете использовать ее для чтения и проверки паролей, сгенерированных другой системой (например, Django), но хэшировать все новые пароли другим алгоритмом, например Argon2 или Bcrypt.
И при этом быть совместимым со всеми этими системами.
///
Создайте служебную функцию для хэширования пароля, поступающего от пользователя.
А затем создайте другую - для проверки соответствия полученного пароля и хранимого хэша.
А затем создайте другую для проверки соответствия полученного пароля и хранимого хэша.
И еще одну - для аутентификации и возврата пользователя.
И еще одну для аутентификации и возврата пользователя.
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
/// note | Технические детали
Если проверить новую (фальшивую) базу данных `fake_users_db`, то можно увидеть, как теперь выглядит хэшированный пароль: `"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`.
Если проверить новую (фальшивую) базу данных `fake_users_db`, то можно увидеть, как теперь выглядит хэшированный пароль: `"$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc"`.
///
## Работа с JWT токенами
## Работа с JWT токенами { #handle-jwt-tokens }
Импортируйте установленные модули.
@ -140,13 +140,13 @@ $ openssl rand -hex 32
Создайте переменную для срока действия токена.
Определите Pydantic Model, которая будет использоваться для формирования ответа на запрос на получение токена.
Определите Pydantic-модель, которая будет использоваться для формирования ответа на запрос на получение токена.
Создайте служебную функцию для генерации нового токена доступа.
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
## Обновление зависимостей
## Обновление зависимостей { #update-the-dependencies }
Обновите `get_current_user` для получения того же токена, что и раньше, но на этот раз с использованием JWT-токенов.
@ -156,7 +156,7 @@ $ openssl rand -hex 32
{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
## Обновление *операции пути* `/token`
## Обновление *операции пути* `/token` { #update-the-token-path-operation }
Создайте `timedelta` со временем истечения срока действия токена.
@ -164,7 +164,7 @@ $ openssl rand -hex 32
{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
### Технические подробности о JWT ключе `sub`
### Технические подробности о JWT ключе `sub` { #technical-details-about-the-jwt-subject-sub }
В спецификации JWT говорится, что существует ключ `sub`, содержащий субъект токена.
@ -186,7 +186,7 @@ JWT может использоваться и для других целей,
Важно помнить, что ключ `sub` должен иметь уникальный идентификатор для всего приложения и представлять собой строку.
## Проверка в действии
## Проверка в действии { #check-it }
Запустите сервер и перейдите к документации: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
@ -201,7 +201,7 @@ JWT может использоваться и для других целей,
Username: `johndoe`
Password: `secret`
/// check | Заметка
/// check | Проверка
Обратите внимание, что нигде в коде не используется открытый текст пароля "`secret`", мы используем только его хэшированную версию.
///
@ -225,10 +225,10 @@ Password: `secret`
<img src="/img/tutorial/security/image10.png">
/// note | Техническая информация
Обратите внимание на заголовок `Authorization`, значение которого начинается с `Bearer`.
Обратите внимание на HTTP-заголовок `Authorization`, значение которого начинается с `Bearer `.
///
## Продвинутое использование `scopes`
## Продвинутое использование `scopes` { #advanced-usage-with-scopes }
В OAuth2 существует понятие "диапазоны" ("`scopes`").
@ -236,9 +236,9 @@ Password: `secret`
Затем вы можете передать этот токен непосредственно пользователю или третьей стороне для взаимодействия с вашим API с определенным набором ограничений.
О том, как их использовать и как они интегрированы в **FastAPI**, читайте далее в **Руководстве пользователя**.
О том, как их использовать и как они интегрированы в **FastAPI**, читайте далее в **Расширенном руководстве пользователя**.
## Резюме
## Резюме { #recap }
С учетом того, что вы видели до сих пор, вы можете создать безопасное приложение **FastAPI**, используя такие стандарты, как OAuth2 и JWT.
@ -252,10 +252,10 @@ Password: `secret`
Он предоставляет вам полную свободу действий, позволяя выбирать то, что лучше всего подходит для вашего проекта.
Вы можете напрямую использовать многие хорошо поддерживаемые и широко распространенные пакеты, такие как `passlib` и `PyJWT`, поскольку **FastAPI** не требует сложных механизмов для интеграции внешних пакетов.
Вы можете напрямую использовать многие хорошо поддерживаемые и широко распространенные пакеты, такие как `pwdlib` и `PyJWT`, поскольку **FastAPI** не требует сложных механизмов для интеграции внешних пакетов.
Напротив, он предоставляет инструменты, позволяющие максимально упростить этот процесс без ущерба для гибкости, надежности и безопасности.
При этом вы можете использовать и реализовывать безопасные стандартные протоколы, такие как OAuth2, относительно простым способом.
В **Руководстве пользователя** вы можете узнать больше о том, как использовать "диапазоны" ("`scopes`") OAuth2 для создания более точно настроенной системы разрешений в соответствии с теми же стандартами. OAuth2 с диапазонами - это механизм, используемый многими крупными провайдерами сервиса аутентификации, такими как Facebook, Google, GitHub, Microsoft, X (Twitter) и др., для авторизации сторонних приложений на взаимодействие с их API от имени их пользователей.
В **Расширенном руководстве пользователя** вы можете узнать больше о том, как использовать "диапазоны" ("`scopes`") OAuth2 для создания более точно настроенной системы разрешений в соответствии с теми же стандартами. OAuth2 с диапазонами это механизм, используемый многими крупными провайдерами сервиса аутентификации, такими как Facebook, Google, GitHub, Microsoft, X (Twitter) и др., для авторизации сторонних приложений на взаимодействие с их API от имени их пользователей.

Loading…
Cancel
Save