django的跨域请求设置
问题引出
由于django本身的权限管理是基于cookie来认证的,而整个过程并不需要前端做什么,直接后端完成;但跨域的时候,产生几个问题;
- django如何跨域?
- django跨域后可以正常的写入cookie吗?
其实,跨域实现的方法有很多种,可以查看前端常见跨域解决方案(全),在此我们使用cors跨域的方式
cors跨域概述
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)
相关内容可以参考跨域CORS原理及调用具体示例
引起我们注意的一点就是同为post请求,当
Content-Type的值为application/json时,就变成了非简单请求,基础表现就是浏览器会先发一个”预检”请求
django跨域设置
- 执行安装
1 | # https://github.com/ottoyiu/django-cors-headers/ |
- 配置settings.py
1 | INSTALLED_APPS = ( |
显式设置cookie
1 | # view.py |
前端设置
前端默认不允许跨域携带cookies,需进行显式的设置;不同的库可能有一些细微的差别;
需要注意的是,以原生表单的形式,发起post请求,是可以携带cookie自动跨域的,无需其他设置;form表单可以跨域一个是历史原因要保持兼容性,一个是form表单会刷新页面不会把结果返回给js,所以相对安全,但其实请求已经发送出去了,你只是拿不到响应而已;这个问题会引起CSRF攻击;
1 | // 原生js(亲测可用,其余未作测试) |
突然来的疑问
写到此时,我所作的测试都是在本地测的,服务器端在localhost:8000,前端在localhost:8888;而跨域操作所写的cookie均在localhost之下,这样就有一个问题,跨域读写的cookie到底是哪里?是发起请求页的域还是请求地址的域?
解答疑问
我们得到的答案是cors跨域读写的cookie都是请求地址的cookie;比如我们请求第三方cdn,并不会携带本站的cookie,发送跨域请求也一样,只会携带请求指向地址的域的cookie。(这也是跨站伪造请求csrf的原理)
服务器如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。
如果非要跨域写cookie呢?有什么办法吗?
跨域写本域cookie
查到的方法如下:
可以通过ngix反向代理跨域配置:proxy_cookie_domain b.com a.com;
也可以通过中间件http-proxy-middleware代理跨域时,配置加上cookieDomainRewrite: ‘a.com’参数,都是用来修改转发过来的cookie中域名为当前a.com域,所以实现了a.com下cookie写入。