6.2 Middleware (CORS, Session, Custom)
9 из 9 шагов пройдено
7 из 7 баллов  получено

CORS в FastAPI

Совместное использование ресурсов между источниками (CORS) служит правилом, которое предотвращает доступ незарегистрированных клиентов к ресурсу. Когда наш веб-API используется внешним приложением, браузер не разрешает HTTP-запросы из разных источников. Это означает, что доступ к ресурсам возможен только из точного источника, как API или источников, разрешенных API.

FastAPI предоставляет CORS middleware, CORSMiddleware, которое позволяет нам регистрировать домены, которые могут получить доступ к нашему API. Middleware принимает массив источников, которым будет разрешен доступ к ресурсам на сервере.

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

  • allow_origins: Список источников (доменов), которым разрешен доступ к вашему API. Вы можете использовать ["*"], чтобы разрешить все источники, но это не рекомендуется по соображениям безопасности.

  • allow_methods: Список методов HTTP, которые разрешены для запросов между различными источниками (cross-origin). По умолчанию он включает в себя ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]

  • allow_headers: Список заголовков HTTP, которые разрешены для запросов между различными источниками. По умолчанию он включает в себя ["*"], что означает, что все заголовки разрешены.

  • allow_credentials: Булевый флаг, указывающий, разрешены ли файлы cookie и заголовки авторизации для запросов между различными источниками. По умолчанию установлено значение False.

  • expose_headers: Список заголовков HTTP, которые доступны браузеру в ответе. По умолчанию это пустой список.

  • max_age: целое число, которое определяет максимальное количество секунд, в течение которых браузер может кэшировать Preflight запрос. По умолчанию он установлен на 600.

Как использовать CORSMiddleware?

Например, чтобы разрешить доступ к нашему API только от https://stepik.org, мы определяем URL-адреса в массиве:

origins = [
    “https://stepik.org”,
]

Чтобы разрешить запросы от любого клиента, массив origins будет содержать только одно значение — звездочку (*). Звездочка — это подстановочный знак, который указывает нашему API разрешать запросы из любого места.

Чтобы использовать CORSMiddleware в приложении FastAPI, вам нужно импортировать его из fastapi.middleware.cors и добавить в экземпляр приложения с помощью метода add_middleware. Например:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost:3000",
    "https://example.com",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
async def main():
    return {"message": "Hello World"}

На этот раз мы использовали функцию add_middleware() FastAPI, чтобы добавить поддержку CORS в наше приложение. Помимо allow_origins, нам также необходимо добавить в CORSMiddleware параметр allow_credentials, который добавляет Access-Control-Allow-Credentials: true в заголовок ответа, чтобы браузер мог распознавать совпадения адресов домена и отправлять файл cookie авторизации для разрешения запроса.

Чтобы проверить, работает ли наша конфигурация CORS, как ожидалось, отправим запрос на API. Для этого создадим любой html файл, следующего содержания:

<!DOCTYPE html>
<html>
   <body>
      <h1>Send JS request</h1>
      <button onclick="getData()">Click me</button>
      <script>
         function getData() {
            fetch('http://127.0.0.1:8000/')
               .then(resp => resp.json())
               .then(data => {
                  console.log(data);
               })
               .catch(error => {
                  console.error(error);
               });
         }
      </script>
   </body>
</html>

Запустим FastAPI через uvicorn сервер, и откроем html файл в браузере. В нем нажмем кнопку Click me и посмотрим логи браузера:

[Error] Origin null is not allowed by Access-Control-Allow-Origin. Status code: 200
[Error] Fetch API cannot load http://127.0.0.1:8000/ due to access control checks.
[Error] Failed to load resource: Origin null is not allowed by Access-Control-Allow-Origin. Status code: 200 (127.0.0.1, line 0)

Мы получим ошибку, так как нашему приложению разрешены запросы лишь от следующих адресов:

    "http://localhost:3000",
    "https://example.com",

Если браузер делает запрос из локального файла (например, file://.../main.html), мы сталкиваемся с тем, что наш источник запроса должен быть указан как "null". Изменим этот список разрешенных источников:

origins = [
    "http://localhost:3000",
    "https://example.com",
    "null"
]

И теперь открыв html файл в браузере и сделав запрос, мы увидим в консоли следующий текст:

{message: "Hello World"}

Вы также можете проверить заголовки ответов и посмотреть их в браузере:

HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: null
Content-Length: 25
Content-Type: application/json
Date: Thu, 02 May 2024 06:50:07 GMT
Server: uvicorn
Vary: Origin

CORS - это полезная функция для веб-приложений, которым необходимо взаимодействовать с API, размещенными на разных серверах или доменах. FastAPI позволяет легко включать и настраивать CORS для ваших конечных точек API всего за несколько строк кода.

В следующем шаге мы продолжим знакомиться с Middleware в FastAPI.


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

Всем привет! Возможно я что-то не верно делаю, тогда буду признателен, если коллеги подскажут.

У меня 22 убунта и яндекс в виде браузера. На "null" в списке разрешенных источников сервер не реагирует и продолжает не пускать, но  'http://localhost:63342'  пропускает. Это является ошибкой?

@Алексей_Бойко, Если не ошибаюсь, это служебный порт PyCharm

@Илья_Перминов, Спасибо, начинаю понимать!