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.