Stage 6. CORS Fundamentals
CORS (Cross-Origin Resource Sharing) — это правило браузера, которое решает, могут ли скрипты страницы читать ответ от другого origin. Важно: CORS не «включает безопасность API целиком». Он контролирует именно доступ браузерного кода к ответу. Поэтому ситуация «сервер вернул 200, но фронтенд всё равно получил CORS error» абсолютно нормальна.
1. Что такое origin простыми словами
Origin состоит из трёх частей: scheme + host + port.
https://app.example.comиhttps://api.example.com— разные origin.http://app.example.comиhttps://app.example.com— тоже разные origin.- Даже один и тот же хост с разными портами считается разным origin.
Если origin отличается, браузер включает CORS-проверки.
2. Как работает CORS по шагам
| Шаг | Что делает браузер | Что должен сделать сервер |
|---|---|---|
| 1. Проверка origin | Определяет, что запрос cross-origin | Быть готовым вернуть CORS-заголовки |
| 2. Preflight (иногда) | Отправляет OPTIONS с вопросом о методе/заголовках | Вернуть корректные Access-Control-Allow-* |
| 3. Основной запрос | Отправляет реальный GET/POST/... только если preflight прошёл | Вернуть CORS-заголовки и на основной ответ |
| 4. Решение браузера | Разрешает или блокирует доступ JS к ответу | Политика должна совпадать с реальным клиентом |
3. Когда нужен preflight
Preflight чаще всего появляется, если запрос не «простой»: например, метод PUT/DELETE, нестандартные заголовки (Authorization) или особый Content-Type. Тогда браузер сначала отправляет OPTIONS.
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization, Content-Type
Если сервер не ответил подходящими Access-Control-Allow-*, браузер не даст скрипту страницы прочитать основной ответ.
4. Минимально понятный набор CORS-заголовков
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Headers: Authorization,Content-Type
Access-Control-Allow-Credentials: true
Практический принцип: чем точнее политика, тем лучше. Не нужно разрешать всё «на всякий случай».
5. Частая ошибка с credentials
Нельзя сочетать:
Access-Control-Allow-Origin: *Access-Control-Allow-Credentials: true
Для запросов с cookie/credentials сервер обязан вернуть конкретный origin, иначе браузер заблокирует доступ.
6. CORS, аутентификация и CSRF — это не одно и то же
- CORS: решает, может ли браузерный JS читать cross-origin ответ.
- Authentication: проверяет, кто клиент (токен, сессия).
- CSRF protection: защищает от нежелательных state-changing запросов от имени пользователя.
Эти механизмы работают вместе, но решают разные задачи.
7. Как отлаживать CORS без угадывания
- Открыть DevTools →
Network. - Найти пару запросов: preflight
OPTIONSи основной. - Сверить
Origin,Access-Control-Request-*иAccess-Control-Allow-*. - Проверить, используется ли cookie/credentials и корректен ли
Allow-Origin. - Только после этого искать проблему в endpoint-логике.
Практический сценарий
После переезда frontend на новый домен запрос GET /profile начал возвращать CORS-ошибку в браузере, хотя в backend-логах всё выглядело успешно. Причина оказалась в API Gateway: в preflight-ответе отсутствовал Access-Control-Allow-Headers: Authorization. Сервер отвечал 200, но браузер блокировал следующий основной запрос для скрипта страницы. После правки CORS-политики и добавления e2e-проверки для cross-origin сценария проблема была закрыта.