Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Зачем нужен CORS
CORS (Cross-Origin Resource Sharing) - это механизм безопасности в браузере, который контролирует доступ к ресурсам между разными доменами. Без него браузер блокирует запросы для защиты пользователя.
Проблема: Same-Origin Policy
Есть вредоносный сайт evil.com:
<script>
// Отправляю запрос на twitch.tv (где ты залогинен)
fetch('https://twitch.tv/api/get-payment-info')
.then(data => send_to_attacker(data))
</script>
Без защиты: браузер отправляет запрос
→ Твои кукиз от twitch.tv отправляются
→ Злоумышленник получает твои данные
→災害!
Решение: Same-Origin Policy
Same Origin = Protocol + Domain + Port
https://api.example.com:8000
├── Protocol: https
├── Domain: api.example.com
└── Port: 8000
Другие origins:
https://example.com:8000 ❌ Разный домен
http://api.example.com:8000 ❌ Разный протокол
https://api.example.com:8001 ❌ Разный порт
Как браузер блокирует запросы
# Frontend на https://localhost:3000
fetch('https://api.example.com/users')
# Браузер:
# 1. Проверяет origin источника: https://localhost:3000
# 2. Проверяет origin целевой страницы: https://api.example.com
# 3. Они разные → браузер блокирует запрос!
# Ошибка в консоли:
# Access to XMLHttpRequest at 'https://api.example.com/users'
# from origin 'https://localhost:3000'
# has been blocked by CORS policy
CORS - разрешить доступ
# FastAPI API
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=[
"https://example.com",
"https://app.example.com",
"http://localhost:3000" # Разработка
],
allow_credentials=True,
allow_methods=["*"], # GET, POST, PUT, DELETE и т.д.
allow_headers=["*"], # Любые заголовки
)
@app.get("/api/users")
async def get_users():
return [{"id": 1, "name": "Alice"}]
Как CORS работает: Preflight запрос
Шаг 1: Браузер отправляет OPTIONS запрос (preflight)
Отправляю:
OPTIONS /api/users HTTP/1.1
Host: api.example.com
Origin: https://localhost:3000
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
Шаг 2: API отвечает
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://localhost:3000
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 3600
Шаг 3: Если все ОК - браузер отправляет реальный запрос
POST /api/users HTTP/1.1
Host: api.example.com
Origin: https://localhost:3000
Content-Type: application/json
{"name": "Bob"}
Практический пример: Django
# settings.py
INSTALLED_APPS = [
'corsheaders',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
]
CORS_ALLOWED_ORIGINS = [
"https://example.com",
"http://localhost:3000",
"http://localhost:5173", # Vite
]
CORS_ALLOW_CREDENTIALS = True # Отправлять cookies
Когда CORS блокирует
# 1. Запросы с разными origin
fetch('https://evil.com/steal-data') # ❌ Блокирован
# 2. Custom headers
fetch('/api/users', {
headers: {
'X-Custom-Header': 'value' # ❌ Блокирован (нужен preflight)
}
})
# 3. POST с Content-Type: application/json
fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({...}) # ❌ Блокирован (нужен preflight)
})
# 4. Cookies с credentials
fetch('/api/users', {
credentials: 'include' # ❌ Блокирован (нужно разрешить)
})
Когда CORS НЕ блокирует (Simple Requests)
# GET запрос с базовыми заголовками
fetch('https://api.example.com/users')
# ✅ Работает (простой запрос)
# POST с application/x-www-form-urlencoded
fetch('/api/users', {
method: 'POST',
body: 'name=Alice'
})
# ✅ Работает
Правила для simple requests
Метод: GET, HEAD, POST
Заголовки:
- Accept
- Accept-Language
- Content-Language
- Content-Type: только application/x-www-form-urlencoded,
multipart/form-data, text/plain
Частые ошибки
# ❌ Неправильно - слишком разрешительно
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Все домены!
allow_credentials=True, # Отправлять cookies
)
# Это противоречиво и небезопасно
# ✅ Правильно
app.add_middleware(
CORSMiddleware,
allow_origins=["https://example.com"],
allow_credentials=True,
)
Когда CORS не проблема
CORS блокирует браузерные запросы
Так что это НЕ защита от:
✓ Запросов с сервера на сервер
✓ cURL запросов
✓ Postman запросов
✓ Mobile приложений (нет браузера)
Вывод
CORS - это защита браузера от XSS атак. Это не мешает разработке, а помогает:
- Явно указать, кто может использовать твой API
- Защитить пользователей от вредоносных сайтов
- Предотвратить утечку данных
Просто правильно настрой CORS в своем API и забудь о проблемах.