Что такое CORS и как его настроить?react-90

Что такое CORS?

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

Как работает CORS?

  1. Same-Origin Policy (Политика одинакового источника):

    • Браузер по умолчанию блокирует запросы между разными доменами
    • "Источник" (origin) определяется как комбинация: протокол + домен + порт
  2. CORS Headers (Заголовки CORS):

    • Сервер должен явно разрешить кросс-доменные запросы
    • Используются специальные HTTP-заголовки

Основные заголовки CORS

1. Со стороны сервера:

  • Access-Control-Allow-Origin: разрешенные домены (* для всех)
  • Access-Control-Allow-Methods: разрешенные HTTP-методы
  • Access-Control-Allow-Headers: разрешенные заголовки запроса
  • Access-Control-Allow-Credentials: разрешение передавать куки
  • Access-Control-Max-Age: кэширование настроек CORS

2. Со стороны клиента:

  • Origin: текущий источник запроса
  • Access-Control-Request-Method: метод для предварительного запроса
  • Access-Control-Request-Headers: заголовки для предварительного запроса

Настройка CORS на сервере

1. Express.js

const express = require('express');
const cors = require('cors');

const app = express();

// Простая настройка (разрешить все домены)
app.use(cors());

// Кастомная настройка
app.use(cors({
  origin: 'https://your-frontend.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true
}));

// Для конкретного маршрута
app.get('/api/data', cors(), (req, res) => {
  res.json({ data: 'Some data' });
});

2. Django

# settings.py
CORS_ALLOWED_ORIGINS = [
    "https://your-frontend.com",
    "http://localhost:3000",
]

# Или разрешить все:
CORS_ALLOW_ALL_ORIGINS = True

3. Nginx

location /api/ {
    add_header 'Access-Control-Allow-Origin' 'https://your-frontend.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,Authorization';
    add_header 'Access-Control-Allow-Credentials' 'true';

    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
    }
}

Предварительные запросы

Для "непростых" запросов браузер сначала отправляет OPTIONS-запрос для проверки разрешений:

  1. Простые запросы (не требуют preflight):

    • GET, HEAD, POST
    • Ограниченный набор заголовков
    • Content-Type: text/plain, application/x-www-form-urlencoded, multipart/form-data
  2. Не простые запросы (требуют preflight):

    • PUT, DELETE, PATCH
    • Пользовательские заголовки
    • Content-Type: application/json

Решение проблем с CORS в разработке

1. Прокси в package.json

{
  "proxy": "http://localhost:5000"
}

2. Настройка прокси в vite.config.js

export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:5000',
        changeOrigin: true,
        rewrite: path => path.replace(/^\/api/, '')
      }
    }
  }
})

3. Расширение для браузера

  • Например, "Allow CORS: Access-Control-Allow-Origin"

Безопасность CORS

  1. Не используйте Access-Control-Allow-Origin: * с учетными данными
  2. Точно указывайте разрешенные домены вместо wildcard
  3. Ограничивайте разрешенные методы и заголовки
  4. Используйте CORS вместе с другими мерами безопасности (CSRF-токены, аутентификация)

Ошибки CORS и их решение

  1. No 'Access-Control-Allow-Origin' header:

    • Настроить сервер для отправки правильных заголовков
  2. Credentials not supported when CORS is wildcard:

    • Указать конкретный домен вместо *
    • Добавить Access-Control-Allow-Credentials: true
  3. Method not allowed:

    • Добавить метод в Access-Control-Allow-Methods

Пример полной настройки CORS

// Сервер на Node.js с полной CORS-настройкой
app.use((req, res, next) => {
  const allowedOrigins = ['https://production.com', 'http://localhost:3000'];
  const origin = req.headers.origin;

  if (allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }

  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.header('Access-Control-Allow-Credentials', 'true');
  res.header('Access-Control-Max-Age', '86400');

  if (req.method === 'OPTIONS') {
    return res.sendStatus(200);
  }

  next();
});

Резюмируем

CORS — это важный механизм безопасности браузеров, требующий правильной настройки как на сервере (через специальные заголовки), так и на клиенте. Для разработки можно использовать прокси, а в продакшне необходимо точно настраивать разрешенные домены, методы и заголовки для баланса между функциональностью и безопасностью.