Перейти к содержанию

CORS (Cross-Origin Resource Sharing)

Понятие CORS или "Cross-Origin Resource Sharing" относится к ситуациям, при которых запущенный в браузере фронтенд содержит JavaScript-код, который взаимодействует с бэкендом, находящимся на другом "источнике" ("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, и если бэкенд вернёт соответствующие заголовки для авторизации взаимодействия с другим источником (http://localhost:8080), то браузер разрешит JavaScript-коду на фронтенде отправить запрос на этот бэкенд.

Чтобы это работало, у бэкенда должен быть список "разрешённых источников" ("allowed origins").

В таком случае этот список должен содержать http://localhost:8080, чтобы фронтенд работал корректно.

Подстановочный символ "*"

В качестве списка источников можно указать подстановочный символ "*" ("wildcard"), чтобы разрешить любые источники.

Но тогда не будут разрешены некоторые виды взаимодействия, включая всё связанное с учётными данными: куки, заголовки Authorization с Bearer-токенами наподобие тех, которые мы использовали ранее и т.п.

Поэтому, чтобы всё работало корректно, лучше явно указывать список разрешённых источников.

Использование CORSMiddleware

Вы можете настроить этот механизм в вашем FastAPI приложении, используя CORSMiddleware.

  • Импортируйте CORSMiddleware.
  • Создайте список разрешённых источников (в виде строк).
  • Добавьте его как "middleware" к вашему FastAPI приложению.

Вы также можете указать, разрешает ли ваш бэкенд использование:

  • Учётных данных (включая заголовки Authorization, куки и т.п.).
  • Отдельных 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 - указывает, что куки разрешены в кросс-доменных запросах. По умолчанию равно False. Также, allow_origins нельзя присвоить ['*'], если разрешено использование учётных данных. В таком случае должен быть указан список источников.
  • expose_headers - Указывает любые заголовки ответа, которые должны быть доступны браузеру. По умолчанию равно [].
  • max_age - Устанавливает максимальное время в секундах, в течение которого браузер кэширует CORS-ответы. По умолчанию равно 600.

CORSMiddleware отвечает на два типа HTTP-запросов...

CORS-запросы с предварительной проверкой

Это любые OPTIONS запросы с заголовками Origin и Access-Control-Request-Method.

В этом случае middleware перехватит входящий запрос и отправит соответствующие CORS-заголовки в ответе, а также ответ 200 или 400 в информационных целях.

Простые запросы

Любые запросы с заголовком Origin. В этом случае middleware передаст запрос дальше как обычно, но добавит соответствующие CORS-заголовки к ответу.

Больше информации

Для получения более подробной информации о CORS, обратитесь к Документации CORS от Mozilla.

Технические детали

Вы также можете использовать from starlette.middleware.cors import CORSMiddleware.

FastAPI предоставляет несколько middleware в fastapi.middleware только для вашего удобства как разработчика. Но большинство доступных middleware взяты напрямую из Starlette.