ASP.NET Core – CORS (Cross-Origin Resource Sharing)

参考

Docs – Enable Cross-Origin Requests (CORS) in ASP.NET Core

 

介绍

CORS (Cross-Origin Resource Sharing) 讲的是游览器对跨域服务端发起 HTTP request (Ajax),被游览器禁止读取。

Chrome DevTools 会显示下面这些 error.

早年的解决方法是用 JSONP (用 <script> 发请求,服务端配合返回 JavaScript 并且调用一个全局方法,方法名字是通过 request query parameters 得知的,最后把资料传入方法中)。

现今只需要加上一些 response header 就可以了。

 

怎样算跨域

1. Domain 不一样

abc.com 和 abc.net

 

2. Sub domain 不一样

abc.com 和 www.abc.com

 

3. Scheme 不一样

http 和 https

 

4. Port 不一样

localhost:4200 和 localhost:61547

 

基本用法: AddCors & UseCors

和其它 ASP.NET Core module 用法差不多. Service.AddCors, App.UseCors

AddCors (for service)

创建 default policy, by pass all origin (这个适合在开发阶段, 下面会讲 production 阶段应该限制多一点, 不可以 by pass all)

builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy =>
    {
        policy.AllowAnyOrigin()
              .AllowAnyMethod()
              .AllowAnyHeader();
    });
});

UseCors (for middleware)

app.UseHttpsRedirection();
app.UseCors();
app.UseAuthorization();

位置很重要哦. 如果 JS 会请求 static file 的话, 那还得放到 app.UseStaticFiles 之上.

 

Policy Configuration

allow header & method

policy.AllowAnyOrigin()
      .AllowAnyMethod()
      .AllowAnyHeader();

method 和 header 是 for Preflight request (OPTIONS) 用的. 通常 set any 是 ok 的.

如果 request 有自定义 header,那也需要设置 header。

要限制也是可以

policy.WithMethods("POST", "PUT");

最终会输出

allow origin

origin 最好不要 set any. 很危险. 指定给需要的 origin 就好了. 

policy.WithOrigins("https://192.168.1.152:4202");

注意, origin 的结尾不可以有 slash.

allow credentials

如果 request 要携带 cookie 的话需要特别开启

policy.AllowCredentials();

有用 SignalR 的话, 也一定要开启, 参考: Security considerations in ASP.NET Core SignalR

另外 AllowAnyOrigin 和 AllowCredentials 不可以一起使用 (应该是担心安全隐患太大吧)

allow exposed headers

跨域默认只允许 client 访问一些 response header

policy.WithExposedHeaders(“specify-header-name”, "x-custom-header");

通过 WithExposedHeaders 可以配置. 指定某个名字, 或者 by pass all 就用关键字 "x-custom-header"

 

Policy 管理

上面的例子在管理上是比较简单的. 一个项目一个配置就 ok 了.

但如果遇到比较复杂的项目就需要多一点管理了. 比如多个 Policy. 有些 Controller 允许 CORS 有些不允许.

Multiple Policy

上面我们用的是 AddDefaultPolicy, 这里用的是 AddPolicy 配上 policy name. 可以一直 AddPolicy, 只要确保名字是 unique 就可以了.

builder.Services.AddCors(options =>
{
    options.AddPolicy(
        name: "MyFirstCorsPolicy",
        configurePolicy: policy =>
        {
            policy.WithOrigins(new[] { "https://192.168.1.152:4202" }).AllowAnyHeader().AllowAnyMethod().AllowCredentials();
        }
    );
});

[EnableCors] 和 [DisableCors]

可以指定某个 Controller 使用哪一个 CORS Policy, 也可以 disable 某一个 Action

UseCors

不管是 default policy 还是 policy with name, 一定要调用 app.UseCors

app.UseCors();

app.UseCors(), 没有声明 policy name, 表示所有 Controller 使用 default policy (如果有 config default policy 的话, 没有的话 Controller 就得用 attribute 来控制)

app.UseCors("MyFirstCorsPolicy");

with policy name 表示所有 Controller 使用 MyFirstCorsPolicy policy, attribute 可以 override 这个设置.

简而言之就是, 用 attribute 去控制 Controller 和 Action. 用 app.UseCors 做全局控制 (不想全局控制, 就不要 set default policy, 但记得, 无论如何 app.UseCors 依然是需要调用的)

 

posted @ 2022-05-23 13:14  兴杰  阅读(269)  评论(0编辑  收藏  举报