前后端分离,或者微服务架构都会遇到跨域问题
1、什么是跨域
1.1CSRF攻击
CSRF攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任,以用户身份在攻击页面对目标网站发起伪造用户操作的请求,达到攻击目的。
1.2同源策略(Same-origin Policy)
浏览器对非同源脚本的限制措施是对同源策略的具体实现
1.2 CORS跨源资源共享 Cross-Origin Resource Sharing
CORS是一个新的 W3C 标准,
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers …
举个栗子: severA.com serverB.com两个域名
serverA.com中的页面通过ajax去访问serverB.com,浏览器会在header中添加 origin:serverA.com,
如果response的header中没有Access-Control-Allow-Origin:serverA.com,则浏览器会拦截这次请求,ajax接收不到返回 的结果,web console直接会报错非同源
解决办法:serverB.com在返回请求时要主动在header中加入Access-Control-Allow-Origin等字段,才能不被浏览器拦截,以python django项目为例
pip install django-cors-headers
# setting.py中设置允许跨域
INSTALLED_APPS = [
'corsheaders',
MIDDLEWARE = (
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware', # 注意顺序
...
)
#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'*'
)
1.4直接在浏览器上输入url访问A网站,A网站重定向到B网站,不存在跨域问题,ajax请求跨域才会被拦截
2、跨域重定向
举个栗子: severA.com serverB.com serverC.com三个域名
serverA.com中的页面通过ajax去访问serverB.com,浏览器会在header中添加 origin:serverA.com,serverB在response中设置了Access-Control-Allow-Origin:serverA.com,并以重定向到serverC.com的方式(重定向返回码302)返回,这时浏览器去请求serverC.com,但未能再header中添加origin:serverA.com,因此请求的结果仍被拦截
解决方法
2.1 jsonp
2.2ngnix代理
2.3微服务之API网关:kong
参考https://github.com/Kong/kong
kong内部也集成了ngnix,功能更强大