Настройка CORS-политик для API 1С-Битрикс
CORS (Cross-Origin Resource Sharing) — механизм браузерной безопасности, который блокирует запросы JavaScript к домену, отличному от домена страницы. Если ваш фронтенд на app.example.com делает запросы к API на api.example.com или к Битрикс24 REST — браузер заблокирует запрос без правильных CORS-заголовков. Настройка CORS не защищает сервер (серверные запросы CORS не касаются), но определяет, какие браузерные клиенты могут работать с API.
Как работает CORS
Simple requests (GET, POST с Content-Type: application/x-www-form-urlencoded) браузер отправляет напрямую, но проверяет ответ: если нет заголовка Access-Control-Allow-Origin с нужным значением — JavaScript не получит ответ (запрос ушёл, ответ получен сервером, но браузер скрыл его от JS).
Preflight requests — для нестандартных методов (PUT, DELETE, PATCH) и заголовков (Authorization, Content-Type: application/json). Браузер сначала отправляет OPTIONS-запрос («можно мне это?»), сервер отвечает — и только потом браузер отправляет основной запрос.
Настройка на уровне Nginx
Для API на коробочном Битрикс — CORS лучше настраивать в Nginx, не в PHP. Nginx обработает OPTIONS-preflight без запуска PHP:
location /api/ {
# Список разрешённых источников
set $cors_origin "";
if ($http_origin ~* "^https://(app\.example\.com|admin\.example\.com)$") {
set $cors_origin $http_origin;
}
# Preflight OPTIONS
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PATCH, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-API-Key" always;
add_header Access-Control-Max-Age 3600 always;
add_header Content-Length 0;
return 204;
}
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Credentials true always;
proxy_pass http://php_backend;
}
Access-Control-Allow-Credentials: true — нужен, если запросы идут с cookie (сессии Битрикс). При этом Access-Control-Allow-Origin не может быть * — только конкретный домен.
Настройка через PHP (init.php или middleware)
Если CORS нужно настраивать динамически (разные правила для разных эндпоинтов, список источников из БД):
// /local/php_interface/init.php или middleware API
$allowedOrigins = ['https://app.example.com', 'https://admin.example.com'];
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowedOrigins)) {
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Credentials: true');
header('Vary: Origin'); // Важно для корректного кеширования CDN
}
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: Authorization, Content-Type, X-API-Key');
header('Access-Control-Max-Age: 3600');
http_response_code(204);
exit;
}
Заголовок Vary: Origin обязателен при динамическом CORS — CDN кеширует ответ отдельно для каждого источника.
CORS для Битрикс24 REST API
Облачный Битрикс24 настроить нельзя — заголовки CORS управляются на стороне Битрикс. Для запросов из браузера к portal.bitrix24.ru/rest/ используйте встроенный JS-SDK (BX24.callMethod), который работает внутри iframe приложения и не подвержен CORS-ограничениям. Прямые REST-запросы из браузера к чужому домену Битрикс24 потребуют проксирования через ваш сервер.
Безопасность: что важно не нарушить
Не используйте * с credentials. Access-Control-Allow-Origin: * разрешает всем. Но при Access-Control-Allow-Credentials: true это недопустимо — браузер заблокирует такой ответ. Только конкретные домены.
Валидируйте список источников. Проверку if ($origin === 'https://app.example.com') обходит атакующий с заголовком Origin: https://app.example.com. Нет — это не обход: CORS защищает от браузерных атак, а не от curl. Серверные запросы CORS игнорируют.
Preflight кеш (Max-Age). Значение 3600 означает: браузер не отправляет повторный OPTIONS-запрос в течение часа. Слишком большое значение замедляет обнаружение изменений политики CORS.
| Сценарий | Рекомендация |
|---|---|
| Фронтенд на том же домене | CORS не нужен |
Фронтенд на поддомене (app.example.com → api.example.com) |
CORS с конкретным origin |
| Публичный API для партнёров | CORS * (без credentials) |
| Мобильное приложение (не браузер) | CORS не нужен, запросы серверные |
| Несколько фронтенд-клиентов | Динамический список + Vary: Origin |
Настройка CORS — это 30 минут работы при правильном понимании механизма. Большинство проблем с CORS решаются правильным расположением заголовков (до вывода тела ответа) и корректной обработкой OPTIONS-запросов.







