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
@Илья_Перминов, Спасибо, начинаю понимать!