asp.net core 系列之允許跨域訪問(Enable Cross-Origin Requests:CORS)


 

這篇文章介紹如何允許跨域訪問

 

瀏覽器安全不允許不同域名的網頁之間發送請求。這種限制叫做同源策略(the same-origin policy)。

同源策略可以防止一個惡意的站點讀取另一個站點的敏感數據。

有時候,你想允許網站發送跨域的請求到你的應用。

 

Cross Origin Resource Sharing ( CORS ) : 

  • 是一個W3C的標准;即允許放寬同源策略
  • 不是一個安全的功能,CORS 放寬了安全性。允許跨域,會讓API更不安全
  • 允許一個服務明確的允許一些跨域請求,而拒絕另外一些
  • 比早些的技術(例如JSONP)更安全,更靈活

 

1.那么同源指的是什么呢

如果兩個URLs是同源的,那么它們有相同的協議,主機(域名),端口

下面兩個是同源的URLs:

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

下面的這些相比於前面的兩個URL,有不同的源:

  • https://example.net – Different domain 不同的域名
  • https://www.example.com/foo.html – Different subdomain 不同的子域名
  • http://example.com/foo.html – Different scheme  不同的協議
  • https://example.com:9000/foo.html – Different port    不同的端口號

IE瀏覽器考慮同源問題的時候,不會考慮端口號

 

2.帶策略的CORS 和中間件

CORS中間件處理跨域請求。下面的代碼允許指定的源能對整個應用進行跨域請求

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
     //AddCors方法的調用會把CORS服務加到應用的服務容器中(service container); services.AddCors(options
=> { options.AddPolicy(MyAllowSpecificOrigins, builder => { builder.WithOrigins("http://example.com", //CorsPolicyBuilder方法可以鏈式調用方法, "http://www.contoso.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); //這個代碼會把CORS策略通過CORS中間件應用到這個應用的所有終端(endpoints);即把跨域作用到整個應用
//注意:1.UseCors必須在UseMvc之前被調用;2. URL末尾不能加/ ;這個url指的是
builder.WithOrigins(url)中的url



        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

這段代碼做了下面的操作

  • 設置策略名為_myAllowSpecificOrigins,這個名字是隨意取的
  • 調用UseCors 擴展方法來允許跨域
  • 調用帶有lambda表達式的 AddCors 方法。lambda表達式取得一個 CorsPlicyBuild對象,進行一些設置

 

CorsPolicyBuilder方法可以鏈式調用方法:

builder.WithOrigins("http://example.com",
                                "http://www.contoso.com")
                                .AllowAnyHeader()
                                .AllowAnyMethod();

 

測試跨域

 

3.使用[EnableCors]屬性設置允許跨域

[EnableCors]屬性提供了另一種方式設置跨域。即可以只設置選擇的終端,而不是所有的終端.

這里不同於上面的那種方式,上面的方式是應用的所有終端都會被設置允許跨域;

而這里只是設置了[EnableCors]屬性的終端;

 

使用[EnableCors]來指定默認的策略,而[EnableCors("{Policy String}")] 指定了特定的策略;

 

[EnableCors]屬性應用於:

  • Razor Page PageModel
  • Controller
  • Controller action method

 

你可以使用[EnableCors]屬性應用不同的策略到 controller/page-model/action 中;

當[EnableCors]屬性應用到 controller/page-model/action ,並且CORS在中間件被允許了(指【Enable("{Policy String}")】的方式),這兩種策略就都被使用了;

不推薦結合使用策略;使用[EnableCors]屬性或者中間件,而不是在相同的應用中使用兩個

 

下面的代碼給每個方法使用了一種策略

[Route("api/[controller]")]
[ApiController]
public class WidgetController : ControllerBase
{
    // GET api/values
    [EnableCors("AnotherPolicy")]
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "green widget", "red widget" };
    }

    // GET api/values/5
    [EnableCors]        // Default policy.
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        switch (id)
        {
            case 1:
                return "green widget";
            case 2:
                return "red widget";
            default:
                return NotFound();
        }
    }
}

 

下面的代碼創建了一個跨越默認策略和一個名字叫“AnotherPolicy”的策略:

public class StartupMultiPolicy
{
    public StartupMultiPolicy(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        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(); }); });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

 

另,其實還有[DisableCors]屬性可以禁止CORS,這里先暫時不做講解

 

 

...未完,待續

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM