# CORS (Обмін ресурсами між різними джерелами) { #cors-cross-origin-resource-sharing }

<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">CORS або "Cross-Origin Resource Sharing"</a> є ситуація, коли фронтенд, що працює в браузері, містить JavaScript-код, який взаємодіє з бекендом, розташованим в іншому "джерелі" (origin).

## Джерело (Origin) { #origin }

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


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

* `http://localhost`
* `https://localhost`
* `http://localhost:8080`

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

## Кроки { #steps }

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

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

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

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

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

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

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

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

## Використання `CORSMiddleware` { #use-corsmiddleware }

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

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


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

* Облікові дані (заголовки авторизації, Cookies, тощо).
* Конкретні HTTP-методи (`POST`, `PUT`) або всі за допомогою `"*"`
* Конкретні HTTP-заголовки або всі за допомогою `"*"`.


{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}


Параметри за замовчуванням у реалізації `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` завжди дозволені для <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests" class="external-link" rel="noopener" target="_blank">простих CORS-запитів</a>.
* `allow_credentials` - Визначає, чи повинні підтримуватися cookies для міждоменних запитів. За замовчуванням `False`.

    Жоден із параметрів `allow_origins`, `allow_methods` і `allow_headers` не можна встановлювати як `['*']`, якщо `allow_credentials` встановлено як `True`. Усі вони мають бути <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#credentialed_requests_and_wildcards" class="external-link" rel="noopener" target="_blank">явно вказані</a>.

* `expose_headers` - Вказує, які заголовки відповіді повинні бути доступні для браузера. За замовчуванням `[]`.
* `max_age` - Встановлює максимальний час (у секундах) для кешування CORS-відповідей у браузерах. За замовчуванням `600`.

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

### Попередні CORS-запити { #cors-preflight-requests }

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

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

### Прості запити { #simple-requests }

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

## Додаткова інформація { #more-info }

Більше про <abbr title="Cross-Origin Resource Sharing">CORS</abbr> можна дізнатися в <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">документації Mozilla про CORS</a>.

/// note | Технічні деталі

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

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

///
