.Net Core Cors中间件的深入讲解

同源策略和资源跨域共享

1、同源策略

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。

1.1、目的

主要是为了保证用户信息的安全,防止网站窃取用户数据。假如没有同源策略,可能就会有下面这种情况的发生。用户访问两个网站A/B,并登录了A网站,A网站会在计算机本地存储Cookie或者Token等等,在访问B网站的时候,B网站就可以访问这些本地的存储信息,B网站可以使用用户的Cookie去登录A网站,那这样用户信息就被泄露了。

1.2、限制范围   

Cookie、LocalStorage和indexDB无法访问(只有同源的网页才能共享Cookie)

DOM无法获得(父窗口和子窗口的地址是同源的才能获取子窗口的信息)

AJAX请求不能被发送(AJAX请求只能发送给同源的网址)

要知道一点,这些限制其实都是浏览器做的限制。

2、跨域资源共享

跨域资源共享跟同源策略相反。在整个跨域通信过程中,浏览器会自动识别此次请求是否跨域,一旦发现跨域,就自动添加请求头信息(如Origin)或者自动发送一次请求方式为option的预请求。浏览器将CORS请求分为两类:简单请求和非简单请求。

2.1、简单请求

当浏览器的请求方式是Head、Get或者Post,并且HTTP的头信息中不会超出以下字段:

Accept

Accept-Language

Content-Language

Origin

时,浏览器会将该请求定义为简单请求,否则就是非简单请求。当浏览器判断为简单请求后,浏览器会自动再请求报文头中加上Origin字段,表明此次请求来自的地址(协议+域名+端口)。然后服务器需要去判断是否接受这个来源的请求。如果允许服务器端返回的头部中需要有Access-Control-Allow-Origin,其值为请求时Origin字段的值或*(表示接受任意源的请求)。请求头中还会有Access-Control-Allow-Methods表示服务器允许的跨域请求的方式。Access-Control-Allow-Headers表示请求头中允许出现的字段。

2.2、 非简单请求

当浏览器判断为非简单请求后,会发送两次请求,首先浏览器会自动发送一个请求方式为options的请求,并在请求头中

加上Access-Control-Request-Method表示下次请求的方法,

加上Origin表明来源,

加上Access-Control-Request-Headers表示下次请求的请求头中额外的字段。

服务器收到请求后,需要获取这三个请求头中的值,并进行判断,确认是否允许进行跨域。如果服务器返回的请求头中没有任何CORS相关的请求头信息,浏览器会认为不通过预检,也不会进行第二次请求。

服务器如果接受跨域并验证通过了options的请求,会返回Access-Control-Allow-Origin(表明允许跨域请求的源)、Access-Control-Allow-Methods(允许跨域请求的请求方式)、Access-Control-Allow-Headers(允许请求头中包含的额外字段)。然后浏览器才会发送真正的请求。 

.Net Core Cors中间件的深入讲解

                 

(第一次options请求)

.Net Core Cors中间件的深入讲解

(第二次请求)

二、服务端实现CORS

在.Net Core Web Api中使用很简单,首先安装包Microsoft.AspNet.WebApi.Cors,在StartUp中添加下面两句

public void ConfigureServices(IServiceCollection services) { services.AddMvc();        //添加Cors,并配置CorsPolicy services.AddCors(options => options.AddPolicy("CorsTest", p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod())); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); }       //注意UseCors()要在UseMvc()之前 app.UseCors("CorsTest"); app.UseMvc(); }

在使用的时候只需要在Controller或者Action中加上特性[EnableCors("CorsTest")]

[EnableCors("CorsTest")] public class ValuesController : Controller { private ILogger<ValuesController> _logger; public ValuesController(ILogger<ValuesController> logger) { _logger = logger; } [HttpGet] public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } }

现在服务端已经配置好了,现在需要通过前端跨域请求

<html> <head> 测试 </head> <body> 测试 </body> </html> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script type="text/javascript"> $(function () { $.ajax({ type: "get", url: "http://localhost:7000/api/values", beforeSend: function (request) {//在请求报文头中加入Authorization 目的是让请求为非简单请求 request.setRequestHeader("Authorization", "Bearer 071899A00D4D4C5B1C41A6B0211B9399"); }, success: function (result) { alert(result); } }, "json"); }); </script>

测试结果如下图:

.Net Core Cors中间件的深入讲解

                          (options请求)

.Net Core Cors中间件的深入讲解

                        (第二次请求)

上面配置允许所有的地址请求这个接口,也可以单独配置某个地址。

services.AddCors(options => options.AddPolicy("CorsTest", p => p.WithOrigins("http://localhost:8089") .AllowAnyHeader() .AllowAnyMethod()));

 三、解析Cors源码

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdsxjw.html