ASP.NET Core 启用跨域请求

本文翻译整理自:https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1

 一 、Cross-Origin Requests (CORS) 跨域请求  

什么是跨域请求?

浏览器的安全特性阻止一个网页向不同于提供当前网页服务器的域发送请求。这种限制叫做同域策略(same-orign policy)。同域策略阻止恶意网站从另一个网站读取敏感数据。但是有些时候,你可能需要允许其他网站跨域请求到你的应用程序。

那么怎么才能实现跨域请求呢?W3C标准中为我们提供了解决方法:跨域资源共享。

Cross Origin Resource Sharing(CORS): 跨域资源共享

  • 是一个W3C标准,允许一个服务器放宽同域策略
  • 不是安全特性,Cross Origin Resource Sharing(CORS)并没有是网站更加安全,而是放宽了安全特性。允许 CORS 的 API 并不更加安全
  • 允许一个服务器显式的指定允许跨域请求的域而拒绝其他的域
  • 比之前解决跨域请求的技术更加安全和灵活,比如JSONP

 二 、什么是同域                                                

拥有完全相同协议、域名和端口的两个URL才算是同域

比如下面两个URL就是同域

  • https://example.com/foo.html
  • https://example.com/bar.html

下面这些和上面的两个就属于不同域

  • https://example.net – 域不同
  • https://www.example.com/foo.html – 子域不同
  • http://example.com/foo.html – 协议不同
  • https://example.com:9000/foo.html – 端口不同

 三 、如何在ASP.NET Core中启用跨域请求          

在ASP.NET Core中配置跨域请求有以下几种方法:

  1. 使用命名策略和中间件
    使用CORS中间件处理跨域请求,代码如下:
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
    
        public IConfiguration Configuration { get; }
    
        public void ConfigureServices(IServiceCollection services)
        {
            // 配置跨域请求
            services.AddCors(options =>
            {
                options.AddPolicy(MyAllowSpecificOrigins,
                builder =>
                {
                    // 在这里配置允许跨域的域
                    // 比如我们在局域网中开发,测试服务器在另一台电脑,我们的开发电脑的IP是 http://192.168.0.1 我们就可以把开发的IP添加进来,这样在开发调试时就可以做到跨域请求
                    builder.WithOrigins("http://192.168.0.1",
                                        "http://www.example.com");
                });
            });
    
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }
    
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
    
            // 启用跨域请求
            app.UseCors(MyAllowSpecificOrigins); 
    
            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }

    我们分别在 ConfigureServices 和 Configure 中配置和启用跨域请求
    配置的时候,WithOrigins 返回一个 CorsPolicyBuilder 对象,可以链式调用方法,比如 AllowAnyHeader, AllowAnyOrigin 具体作用可以查看文档;

    注意:参数URL不能以斜杠/结尾,如果URL以 / 结尾的话,在方法中对比 URL 就会返回 false,也就是会认为是不同的 URL

    UseCors 通过中间件对所有 endpoints 应用 CORS 策略
    注意:UseCors 的调用必须在 UseRouting 和 UseEndpoints 之间,错误的调用顺序将会引起错误

  2. 使用 Endpoint 路由启用跨域
    使用Endpoint 路由,CORS 可以使用 RequireCors 启用,代码如下:
    app.UseEndpoints(endpoints =>
    {
      endpoints.MapGet("/echo", async context => context.Response.WriteAsync("echo"))
        .RequireCors("policy-name");
    });

    同样的,可以把 CORS 应用到所有控制器上:

    app.UseEndpoints(endpoints =>
    {
      endpoints.MapControllers().RequireCors("policy-name");
    });
  3. 使用特性启用 CORS
    [EnableCors] 特性提供了全局应用 CORS 的途径。[EnableCors] 对选定的终点启用 CORS,而不是应用到全部的终点。
    使用 [EnableCors] 指定默认的策略,[EnableCors("{Policy String}")] 指定特定的策略。
    [EnableCors] 可以应用到以下几个地方:
    - Razor Page PageModel
    - Controller
    - Controller action method
    使用 [EnableCors] 特性,你可以应用不同的策略到 controller/page-model/action。当 [EnableCors] 特性应用到 controller/page-model/action 上,并且 CORS 在中间件中也启用了,那么两者都会起作用。我们的建议是不要叠加策略。使用 [EnableCors] 特性或者使用中间件,不要在同一个应用程序中同时使用。

    [Route("api/[controller]")]
    [ApiController]
    public class WidgetController : ControllerBase
    {
       // 指定策略 [EnableCors("AnotherPolicy")] [HttpGet] public ActionResultstring>> Get() { return new string[] { "green widget", "red widget" }; } [EnableCors] // 默认策略 [HttpGet("{id}")] public ActionResult<string> Get(int id) { switch (id) { case 1: return "green widget"; case 2: return "red widget"; default: return NotFound(); } } }

    设置默认策略:

            services.AddCors(options =>
            {
                options.AddDefaultPolicy(
                    builder =>
                    {
                       
                        builder.WithOrigins("http://example.com",
                                            "http://www.contoso.com");
                    });
    
                options.AddPolicy("AnotherPolicy",
                    builder =>
                    {
                        builder.WithOrigins("http://www.contoso.com")
                                            .AllowAnyHeader()
                                            .AllowAnyMethod();
                    });
    
            });

    关闭CORS
    [DisableCors] 特性可以应用到 controller/page-model/action 用来关闭CORS

你可能感兴趣的:(ASP.NET Core 启用跨域请求)