.NET Core3.1でCORSの設定をする

サーバーサイドとフロントサイド(今回は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を指定する

```csharp
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を設定できます。

```csharp
[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](https://docs.microsoft.com/ja-jp/aspnet/core/security/cors?view=aspnetcore-3.1)
>
> [.NET CORE 2.0 Angular 5: Allowing Cors - Stack Overflow](https://stackoverflow.com/questions/48458631/net-core-2-0-angular-5-allowing-cors)
>
> [ASP.NET Core 3.0 への移行時に悩んだ点と新しくなった Endpoint Routing について - しばやん雑記](https://blog.shibayan.jp/entry/20190925/1569402371)