Перейти до змісту

CORS (Обмін ресурсами між різними джерелами)

CORS або "Обмін ресурсами між різними джерелами" є ситуація, коли фронтенд, що працює в браузері, містить JavaScript-код, який взаємодіє з бекендом, розташованим в іншому "джерелі" (origin).

Джерело (Origin)

Джерело визначається комбінацією протоколу (http, https), домену (myapp.com, localhost, localhost.tiangolo.com), порту (80, 443, 8080).

Наприклад, такі адреси вважаються різними джерелами:

  • http://localhost
  • https://localhost
  • http://localhost:8080

Навіть якщо вони всі містять localhost, вони мають різні протоколи або порти, що робить їх окремими "джерелами".

Кроки

Припустимо, що Ваш фронтенд працює в браузері на http://localhost:8080, а його JavaScript намагається відправити запит до бекенду, який працює на http://localhost (Оскільки ми не вказуємо порт, браузер за замовчуванням припускає порт 80).

Потім браузер надішле HTTP-запит OPTIONS до бекенду на порту :80, і якщо бекенд надішле відповідні заголовки, що дозволяють комунікацію з цього іншого джерела (http://localhost:8080), тоді браузер на порту :8080 дозволить JavaScript у фронтенді надіслати свій запит до бекенду на порту :80.

Щоб досягти цього, бекенд на порту :80 повинен мати список "дозволених джерел".

У цьому випадку список має містити http://localhost:8080, щоб фронтенд на порту :8080 працював коректно.

Символьне підставляння

Можна також оголосити список як "*" ("символьне підставляння"), що означає дозвіл для всіх джерел.

Однак це дозволить лише певні типи комунікації, виключаючи все, що пов'язане з обліковими даними: Cookies, заголовки авторизації, такі як ті, що використовуються з Bearer токенами тощо.

Тому для коректної роботи краще явно вказувати дозволені джерела.

Використання CORSMiddleware

Ви можете налаштувати це у Вашому додатку FastAPI за допомогою CORSMiddleware.

  • Імпортуйте CORSMiddleware.
  • Створіть список дозволених джерел (у вигляді рядків).
  • Додайте його як "middleware" у Ваш додаток FastAPI.

Також можна вказати, чи дозволяє Ваш бекенд:

  • Облікові дані (заголовки авторизації, сookies, тощо).
  • Конкретні HTTP-методи (POST, PUT) або всі за допомогою "*"
  • Конкретні HTTP-заголовки або всі за допомогою "*".
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost.tiangolo.com",
    "https://localhost.tiangolo.com",
    "http://localhost",
    "http://localhost:8080",
]

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


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

Параметри за замовчуванням у CORSMiddleware є досить обмеженими, тому Вам потрібно явно вказати конкретні джерела, методи або заголовки, щоб браузери могли використовувати їх у контексті запитів між різними доменами.

Підтримуються такі аргументи:

  • allow_origins - Список джерел, яким дозволено здійснювати міждоменні запити. Наприклад ['https://example.org', 'https://www.example.org']. Ви можете використовувати ['*'], щоб дозволити всі джерела.
  • allow_origin_regex - Рядок регулярного виразу для відповідності джерелам, яким дозволено здійснювати міждоменні запити. Наприклад, 'https://.*\.example\.org'.
  • allow_methods - Список HTTP-методів, дозволених для міждоменних запитів. За замовчуванням ['GET']. Ви можете використовувати ['*'], щоб дозволити всі стандартні методи.
  • allow_headers - Список HTTP-заголовків, які підтримуються для міждоменних запитів. За замовчуванням []. Ви можете використовувати ['*'], щоб дозволити всі заголовки. Заголовки Accept, Accept-Language, Content-Language і Content-Type завжди дозволені для простих CORS-запитів.
  • allow_credentials - Визначає, чи підтримуються файли cookie для міждоменних запитів. За замовчуванням False. Також, якщо потрібно дозволити обмін обліковими даними (allow_credentials = True), параметр allow_origins не може бути встановлений як ['*'], необхідно вказати конкретні джерела.
  • expose_headers - Вказує, які заголовки відповіді повинні бути доступні для браузера. За замовчуванням [].
  • max_age - Встановлює максимальний час (у секундах) для кешування CORS-відповідей у браузерах. За замовчуванням 600.

Цей middleware обробляє два типи HTTP-запитів...

Попередні CORS-запити (preflight requests)

Це будь-які OPTIONS - запити, що містять заголовки Origin та Access-Control-Request-Method.

У такому випадку middleware перехопить вхідний запит і відповість відповідними CORS-заголовками, повертаючи або 200, або 400 для інформаційних цілей.

Прості запити

Будь-які запити із заголовком Origin. У цьому випадку middleware пропустить запит як звичайний, але додасть відповідні CORS-заголовки у відповідь.

Додаткова інформація

Більше про CORS можна дізнатися в документації Mozilla.

Технічні деталі

Також можна використовувати from starlette.middleware.cors import CORSMiddleware.

FastAPI надає кілька middleware у fastapi.middleware для зручності розробників. Але більшість доступних middleware походять безпосередньо зі Starlette.