サーバーサイドとフロントサイド(今回はAngular)を別サーバーで実装する場合、Hostされるポート番号が異なるため、CORSの設定をする必要がある。
環境
Angular 8.2.14
.NET Core 3.1
サーバーサイド:https://localhost:44342
フロントサイド:http://localhost:4200
※ localhost:4200
はAngularのデフォルトのポート番号
問題
何も設定しないと、フロントサイドからサーバーサイドにhttpリクエストした場合、下記のエラーによりレスポンスが返されない。
Access to XMLHttpRequest at 'https://localhost:44342/api/weatherforecast/getweatherforecast' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Startup.csにCORSの設定を行う
CORSの設定は、Startup.csで行う。
ポイントは
-
app.UseCors();
をapp.UseEndpoints();
の後に呼び出す - 複数のOriginを許可するには
.WithOrigins()
に配列でURLを指定する
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
namespace SampleWebApi
{
public class Startup
{
public Startup(IHostEnvironment env)
{
Configuration = builder.Build();
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// ~省略~
// ↓追加↓
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder => builder
.AllowAnyMethod()
.AllowAnyHeader()
.WithOrigins(new string[] { "http://localhost:4200" })
);
options.AddPolicy("CorsPolicyName",
builder => builder
.AllowAnyMethod()
.AllowAnyHeader()
.WithOrigins(new string[] { "http://localhost:8080" })
);
});
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ~省略~
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
// ↓追加↓
app.UseCors();
}
}
}
APIごとにCORSを設定するには
Controllerの属性に[EnableCore("CorsPolicyName")]
を指定するとAPIごとにCORSを設定できます。
[HttpGet]
[Route("GetWeatherForecast")]
[Authorize]
[EnableCors("CorsPolicyName")]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
参考ページ
ASP.NET Core でのクロスオリジン要求 (CORS) を有効にする | Microsoft Docs
.NET CORE 2.0 Angular 5: Allowing Cors - Stack Overflow
ASP.NET Core 3.0 への移行時に悩んだ点と新しくなった Endpoint Routing について - しばやん雑記