Что такое CORS и как его настроить на бэкенде?

«Что такое CORS и как его настроить на бэкенде?» — вопрос из категории Безопасность, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

CORS (Cross-Origin Resource Sharing) — это механизм безопасности, реализованный в браузерах, который использует дополнительные HTTP-заголовки, чтобы разрешить веб-приложению, работающему на одном источнике (origin, комбинация протокол/домен/порт), получать доступ к ресурсам с другого источника.

Как это работает в DevOps-контексте: Когда фронтенд (например, SPA на https://frontend.com) пытается сделать AJAX-запрос к API на другом домене (https://api.backend.com), браузер отправляет предзапрос (preflight) типа OPTIONS. Сервер (api.backend.com) должен ответить с заголовками, явно разрешающими такой кросс-доменный запрос.

Ключевые заголовки ответа сервера:

  • Access-Control-Allow-Origin: Указывает, с каких источников разрешены запросы (например, https://frontend.com или * для всех).
  • Access-Control-Allow-Methods: Разрешённые HTTP-методы (GET, POST, PUT и т.д.).
  • Access-Control-Allow-Headers: Разрешённые заголовки в запросе (например, Authorization, Content-Type).
  • Access-Control-Allow-Credentials: Если установлен в true, позволяет отправлять куки и данные авторизации. В этом случае Access-Control-Allow-Origin не может быть *.

Пример настройки CORS на уровне обратного прокси (Nginx):

location /api/ {
    # Разрешаем запросы только с конкретного домена
    if ($http_origin ~* (https://frontend.com|https://staging.frontend.com)) {
        set $cors "true";
    }
    if ($request_method = 'OPTIONS') {
        set $cors "${cors}options";
    }
    if ($cors = "trueoptions") {
        add_header 'Access-Control-Allow-Origin' "$http_origin" always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type' always;
        add_header 'Access-Control-Max-Age' 1728000 always;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
    }
    if ($cors = "true") {
        add_header 'Access-Control-Allow-Origin' "$http_origin" always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
    }
    # ... остальная конфигурация проксирования
}

Важно: Для безопасности никогда не используйте Access-Control-Allow-Origin: * в продакшене вместе с Access-Control-Allow-Credentials: true и всегда явно указывайте доверенные домены. Настройку также можно выполнять на уровне самого бэкенд-приложения (например, через middleware в Node.js или Spring).

Видео-ответы