Использование CORS в ASP.NET Core
По умолчанию браузеры отклоняют AJAX-запросы к адресам, расположенных в других доменах. Но иногда такие запросы необходимы. Для того, чтобы это регулировать придумали CORS.
Cross Origin Resource Sharing (CORS) — стандарт W3C, который позволяет определить политики кросс-доменных AJAX-запросов. Подробнее про CORS можно почитать здесь и здесь.
Как видно из спецификаций, управление политиками CORS происходит за счет дополнительных HTTP-запросов и HTTP-заголовков при осуществлении кросс-доменных запросов. В ASP.NET Core существует готовый пакет для настройки политик CORS, что упрощает работу с кросс-доменными запросами.
Установка пакета
В первую очередь следует установить пакет Microsoft.AspNetCore.Cors — в нем находится все необходимое для настройки CORS.
После установки пакета следует зарегистрировать сервис CORS в контейнере ASP.NET:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
}
Настройка источника
Кроме добавления CORS в DI-контейнер, следует указать конвейеру ASP.NET Core о необходимости использования Middleware из пакета Microsoft.AspNetCore.Cors. Сделать это можно вызвав метод UseCors(). В качестве параметра передается выражение, настраивающее политику CORS. Зададим домены, которым можно работать с нашим ресурсом в рамках CORS:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors(builder =>
builder.WithOrigins("https://blog.zwezdin.com/")
);
}
Параметр builder — это объект CorsPolicyBuilder. С его помощью можно указать как именно должен работать CORS для нашего ресурса. Вся дальнейшая настройка CORS производится с его помощью.
Указание HTTP-методов и заголовков
Если вам требуется более тонкая настройка CORS, то следует воспользоваться тем же CorsPolicyBuilder, но задать больше параметров. Например, если в рамках CORS-запросов вы захотите передавать HTTP-заголовки, отличные от стандартных, то такой запрос будет отклонен. Следующая конфигурация позволит работать с нестандартными заголовками, а также указать HTTP-методы, разрешенные для работы и набор хостов-источников:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors(builder =>
builder.WithOrigins("https://blog.zwezdin.com/",
"https://google.com")
.WithHeaders("X-Header1", "X-Header1")
.WithMethods("GET", "POST", "PUT")
);
}
Можно также отменить ограничительную политику и разрешить всё:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors(builder =>
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
);
}
Пользоваться, однако, такой методикой я бы посоветовал с осторожностью.
Определение политик
Если предполагается, что отдельные части приложения должны иметь разное поведение для CORS-запросов, то можно воспользоваться политиками. Политики — это именованый набор правил CORS, аналогичный тому, как это описывалось выше. Описание политик производится в методе AddCors() при добавлении сервиса в DI-контейнер:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(cors =>
{
cors.AddPolicy("Policy1",
builder =>
builder.WithOrigins("https://blog.zwezdin.com/")
.WithHeaders("X-Header1", "X-Header1")
.WithMethods("GET", "POST", "PUT"));
cors.AddPolicy("Policy2",
builder =>
builder.AllowAnyOrigin()
.WithMethods("GET"));
cors.AddPolicy("Policy3",
builder =>
builder.AllowAnyOrigin()
.WithHeaders("X-Header1")
.WithMethods("POST"));
});
}
Здесь определяется три политики с именами Policy1, Policy2 и Policy3. Далее есть несколько способов как эти политики можно применять.
Можно указать имя политики вместо явной конфигурации при добавлении Middleware.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors("Policy2");
}
Такой подход позволяет иметь несколько предопределенных политик и переключать их, например, используя конфигурационный файл.
Если в приложении используется ASP.NET MVC, то политики CORS можно применять к отдельным контроллерам или действиям:
[EnableCors("Policy2")]
public class HomeController : Controller
{
[EnableCors("Policy1")]
public IActionResult Index()
{
return View();
}
[EnableCors("Policy2")]
public IActionResult About()
{
return View();
}
}
Если добавить фильтр CorsAuthorizationFilterFactory глобально, то заданная политика будет применяться ко всем контроллерам/действиям. При этом можно явно указать на какие действия эта политика распространяться не должна:
[EnableCors("Policy2")]
public class HomeController : Controller
{
[EnableCors("Policy1")]
public IActionResult Index()
{
return View();
}
[EnableCors("Policy2")]
public IActionResult About()
{
return View();
}
[DisableCors]
public IActionResult Contact()
{
return View();
}
}
Добавить комментарий