Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Механизм CORS-проверки
CORS (Cross-Origin Resource Sharing) — это механизм безопасности браузеров, который контролирует доступ к ресурсам одного веб-приложения с другого домена (origin). Проверка происходит автоматически браузером перед выполнением «непростых» HTTP-запросов между разными источниками.
Что такое Origin (источник)?
Origin определяется комбинацией протокола, домена и порта. Например:
https://example.com:443иhttps://api.example.com:443— разные origins (разные домены).http://localhost:3000иhttp://localhost:5000— разные origins (разные порты).
Как происходит проверка: пошаговый алгоритм
1. Предварительный запрос (Preflight Request)
Для «непростых» запросов (например, с custom-заголовками, методами кроме GET/POST/HEAD, Content-Type: application/json) браузер автоматически отправляет OPTIONS-запрос перед основным.
OPTIONS /api/data HTTP/1.1
Origin: https://myapp.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Authorization, X-Custom-Header
Host: api.example.com
2. Ответ сервера на preflight
Сервер должен вернуть заголовки, разрешающие или запрещающие CORS:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization, X-Custom-Header, Content-Type
Access-Control-Max-Age: 86400 # Кэширование preflight на 24 часа
3. Проверка браузером
Браузер сравнивает:
- Access-Control-Allow-Origin с origin запроса (должен совпадать или быть
*) - Access-Control-Allow-Methods должен включать метод основного запроса
- Access-Control-Allow-Headers должен включать все запрошенные кастомные заголовки
Если проверка не пройдена — браузер блокирует основной запрос и выбрасывает CORS-ошибку в консоли.
4. Основной запрос
Если preflight успешен, браузер отправляет основной запрос, и сервер должен снова включить CORS-заголовки в ответ:
PUT /api/data HTTP/1.1
Origin: https://myapp.com
Authorization: Bearer token123
Host: api.example.com
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://myapp.com
Access-Control-some-Other: headers...
«Простые» запросы (Simple Requests)
Для GET/POST/HEAD без кастомных заголовков и с допустимыми Content-Type (application/x-www-form-urlencoded, multipart/form-data, text/plain) preflight не отправляется. Но CORS. .
Реализация на C# (ASP.NET Core)
// Program.cs или Startup.cs
app.UseCors(builder =>
{
builder.WithOrigins("https://myapp.com", "http://localhost:3000")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials(); // Для cookies/авторизации
});
// Или более тонкая настройка для отдельных endpoints:
app.MapGet("/api/data", () => "Hello")
.RequireCors("MyPolicy");
// Настройка политики:
var corsPolicy = new CorsPolicyBuilder()
.WithOrigins("https://myapp.com")
.WithMethods("GET", "POST")
.WithHeaders("X-API-Key")
.Build();
Ключевые заголовки CORS
| Заголовок запроса | Заголовок ответа | Назначение |
|---|---|---|
Origin | Access-Control-Allow-Origin | Разрешенные источники |
Access-Control-Request-Method | Access-Control-Allow-Methods | Разрешенные HTTP-методы |
Access-Control-O.Request-Headers | Access-Control-Allow-Headers | Разрешенные заголовки |
| – | Access-Control-Allow-Credentials | Разрешение credentials (cookies, auth) |
| – | Access-Control-Expose-Headers | Какие заголовки доступны JS-коду |
| – | Access-Control-Max-Age | Время кэширования preflight |
Безопасность и best practices
- Не используйте
*дляAccess-Control-Allow-OriginприAllowCredentials— это запрещено спецификацией. - Строго ограничивайте источники в продакшене:
builder.WithOrigins(configuration["AllowedOrigins"].Split(',')) - Используйте политики для разных API — публичные и внутренние endpoints.
- Кэшируйте preflight через
Access-Control-Max-Ageдля производительности. - Учитывайте, что CORS — защита браузера; Postman/cURL игнорируют эти проверки.
CORS-проверка — это не авторизация, а механизм контроля доступа к ресурсам между разными доменами на уровне браузера, предотвращающий атаки типа CSRF и утечку данных.