CORS跨域

  Q: 在Django前后端分离的项目中,我们为前端(www.xxx.site)和后端(api.xxx.site)分别设置了两个不同的域名,浏览器为了安全,会对跨域请求进行限制,前端将无法访问后端提供的接口

  A: CORS

    PS:本文仅讲Django中CORS的配置

1. 什么是CORS跨域?

  在说CORS之前,先说下同源策略,如果协议,端口和主机对于两个页面是相同的,则两个页面具有相同的源,否则就是不同源的。

    CORS(Cross-Origin Resource Sharing 跨源资源共享),当一个请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域

2. 为什么要限制跨域请求?

  跨域请求虽然可以提高页面的体验,但是带来的安全问题也是巨大的,其中最为突出的就是CSRF(Cross-site request forgery)跨站请求伪造。

CSRF攻击的大致原理是:

  1. 用户通过浏览器,访问正常网站A(例如某银行),通过用户的身份认证(比如用户名/密码)成功A网站。
  2. 网站A产生Cookie信息并返回给用户的浏览器; 
  3. 用户保持A网站页面登录状态,在同一浏览器中,打开一个新的TAB页访问恶意网站B;
  4. 网站B接收到用户请求后,返回一些攻击性代码,请求A网站的资源(例如转账请求);
  5. 浏览器执行恶意代码,在用户不知情的情况下携带Cookie信息,向网站A发出请求。
  6. 网站A根据用户的Cookie信息核实用户身份(此时用户在A网站是已登录状态),A网站会处理该请求,导致来自网站B的恶意请求被执行。

3. CORS的作用

  跨域请求主要用于:

    •  调用XMLHttpRequest或fetchAPI通过跨站点方式访问资源
    •  网络字体,例如Bootstrap(通过CSS使用@font-face 跨域调用字体)
    •  通过canvas标签,绘制图表和视频。

4.实现跨域需要的技术手段

① JSONP

  JSONP 是利用浏览器对script的资源引用没有同源限制,通过动态插入一个script标签, 当资源加载到页面后会立即执行的原理实现跨域的。JSONP是一种非正式传输协议,该协议的一个要点就是允许用户传进一个calback或者开始就定义一个回调方法,参数给服务端,然后服务端返回数据时会将这个calback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据J了。JSONP只支持GET请求而不支持POST等其它类型的HTTP请求,它只支持跨城HTTP请求这种情况, 不能解决不同域的两个页面之间如何进行JavaScript调用的问题。JSONP的优势在于支持老式浏览器, 弊端也比较明显:需要客户端和服务创定制进行开发,服务端返回的数据不能是标准的Json数据, 而是callback包裹的数据。

② CORS

  CORS 是现代浏览器支持跨域资源请求的一种方式, 全称是”跨域资源共享“ (Cross origin resource sharing)当使用XMLHmpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头: Access-Control-Alow-Origin.浏览器判断该响应头中是否包含Orgin的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含,浏览器直接驳回,这是我们无法拿到相应的数据。

  CORS与JSONP的使用目的相同,但是比JSONP更强大,CORS支持所有的消览器请求类型,承数的请求数据量更大,开放更简洁,服务国只需要将处理后的数据直接返回,不需要再特殊处理。

5 Django/项目中的配置

①  安装    pip install django-cors-headers 

②  添加应用 -->settings中将corsheaders注册

1 INSTALLED_APPS = (
2     ...
3     'corsheaders',
4     ...
5 )

③ 中间层设置

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    ...
]

 添加白名单:在白名单内的所有域名都可以访问

# CORS
CORS_ORIGIN_WHITELIST = (
    '127.0.0.1:8080',
    'localhost:8080',
    'www.xxx.site:8080',
)
CORS_ALLOW_CREDENTIALS = True  # 允许携带cookie

⑤ 本地host的配置

# 本地调试时 host文件中增加
127.0.0.1 www.xxx.site 

⑥ 完成配置 在浏览器中可以用 www.xxx.site:8080访问后端的接口了

 

猜你喜欢

转载自www.cnblogs.com/Jaho/p/9274796.html