Что такое CORS?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое CORS?
CORS (Cross-Origin Resource Sharing) — это механизм безопасности в браузерах, который позволяет веб-страницам из одного домена (origin) безопасно запрашивать ресурсы (например, данные API, изображения, скрипты) с другого домена. Это механизм, основанный на заголовках HTTP, который расширяет стандартную политику Same-Origin Policy, разрешая контролируемые межсайтовые запросы.
Same-Origin Policy как основа безопасности
Безопасность браузеров исторически базируется на Same-Origin Policy (SOP). Она ограничивает взаимодействие между документами или скриптами, загруженными из разных источников (origin). «Источник» определяется как комбинация:
- Схема (protocol) — например,
http,https - Домен (host) — например,
example.com,localhost - Порт (port) — например,
80,443
Если любая из этих трёх составляющих отличается, то это считается cross-origin (межсайтовым), и такие запросы по умолчанию заблокируются браузером. Например:
- Страница
https://site-a.com/page.htmlпытается сделать AJAX запрос кhttps://api.site-b.com/data.json→ запрос заблокирован SOP. - Та же страница с
http://site-a.comзапрашиваетhttps://site-a.com→ заблокирован, так как схема отличается.
Как работает CORS: механизм заголовков HTTP
CORS работает через добавление специальных заголовков HTTP к запросам и ответам. Основные этапы:
-
Запрос клиента: Когда браузер делает cross-origin запрос (например, через
fetch()илиXMLHttpRequest), он автоматически добавляет заголовокOrigin, указывающий источник текущей страницы.// Пример fetch запроса fetch('https://api.external.com/data', { method: 'GET', headers: { 'Content-Type': 'application/json' } });Браузер добавит:
Origin: https://my-site.com -
Ответ сервера: Сервер должен анализировать заголовок
Originи, если он разрешает запрос с этого источника, добавлять в ответ заголовокAccess-Control-Allow-Originс соответствующим значением.HTTP/1.1 200 OK Access-Control-Allow-Origin: https://my-site.com Content-Type: application/jsonСервер может также указать
*для разрешения всех источников (не рекомендуется для данных с учётом аутентификации). -
Проверка браузера: Браузера проверяет наличие и значение
Access-Control-Allow-Originв ответе. Если заголовок отсутствует или значение не совпадает с текущим источником (или не*), браузер блокирует ответ, и клиентский код не получит данные.
Ключевые заголовки CORS
Origin(заголовок запроса): Указывает источник клиента.Access-Control-Allow-Origin(заголовок ответа): Список разрешённых источников или*.Access-Control-Allow-Methods: Разрешённые HTTP методы (GET, POST, PUT, DELETE, etc.) для cross-origin запросов.Access-Control-Allow-Headers: Разрешённые заголовки, которые клиент может отправлять.Access-Control-Allow-Credentials: Еслиtrue, разрешает включение cookies и заголовков авторизации в cross-origin запросы. В таком случаеAccess-Control-Allow-Originне может быть*.Access-Control-Expose-Headers: Заголовки, которые браузер может «видеть» в ответе (по умолчанию доступны только простые заголовки).Access-Control-Max-Age: Время в секундах, сколько браузер может кэшировать результаты preflight запроса.
Preflight запросы для «небезопасных» методов
Для «безопасных» методов (GET, HEAD, POST с определёнными Content-Type) CORS запрос выполняется сразу. Однако для «небезопасных» методов (PUT, DELETE, POST с «нестандартными» заголовками или Content-Type) браузер сначала отправляет OPTIONS запрос (preflight) для проверки разрешений сервера.
Пример preflight запроса и ответа:
# Preflight запрос (OPTIONS)
OPTIONS /api/data HTTP/1.1
Origin: https://client.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
# Ответ сервера на preflight
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://client.com
Access-Control-Allow-Methods: PUT, GET, POST
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Max-Age: 86400
Если preflight ответ удовлетворяет условиям, браузер отправляет основной запрос.
Примеры сценариев и конфигурации на стороне сервера
Для разрешения CORS на сервере необходимо настроить соответствующие заголовки. Например, в Node.js с Express:
const express = require('express');
const app = express();
// Middleware для CORS
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://trusted-client.com');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Credentials', 'true');
next();
});
app.get('/api/data', (req, res) => {
res.json({ message: 'Данные доступны для cross-origin запроса' });
});
app.listen(3000);
В Nginx можно настроить через конфигурацию:
location /api/ {
add_header 'Access-Control-Allow-Origin' 'https://trusted-client.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
return 204;
}
}
Практические рекомендации для QA Engineer
-
Тестирование CORS: При тестировании веб-приложений и API важно проверять корректность работы CORS:
- Убедиться, что несанкционированные источники блокируются.
- Проверить, что разрешённые источники получают данные.
- Проверить preflight запросы для «небезопасных» операций.
- Тестировать сценарии с credentials (cookies, токены авторизации).
-
Инструменты: Используйте инструменты разработчика браузера (DevTools), чтобы видеть заголовки CORS и ошибки. Также полезны консольные инструменты (curl, Postman) для проверки ответов сервера.
-
Безопасность: CORS — это дополнение безопасности, но не заменяет другие механизмы. Сервер должен дополнительно проверять аутентификацию, авторизацию и валидацию данных, даже если запрос проходит CORS.
-
Частые проблемы: Ошибки типа «CORS policy blocked», «No 'Access-Control-Allow-Origin' header», проблемы с credentials при использовании
Access-Control-Allow-Origin: *.
Таким образом, CORS — это критически важный механизм для современных веб-приложений, которые используют микросервисы, внешние API и распределённые ресурсы. Он обеспечивает безопасное взаимодействие между разными источниками, оставаясь фундаментальным элементом безопасности браузера.