最近在尝试前后端分离的项目的学习开发,前端使用React,后端使用flask。前后端分离的项目中,基本前端后端都会各自启动一个服务,通过api接口调用的方式进行交互。发现一直存在CORS跨域的问题。
CORS
这个问题老生常谈了,参考:千字短文聊聊跨源和跨站以及涉及到的安全问题,总结就是下面的表格
域名 |
表现 |
是否跨站 |
https://www.remex.com:443 |
不同域名 |
跨站 |
https://test.example.top:443 |
子域名不同 |
同站 |
http://www.example.top:443 |
协议不同 |
跨站 |
https://example.top:443 |
www缺省 |
同站 |
https://www.example.top:8080 |
端口不同 |
同站 |
问题描述
假设一个前后端分离的项目,前端域名为 https://www.a.com,后端域名为https://api.a.com:9000,那么当前端发起请求去访问后端接口的时候,很明显跨域了。
浏览器的CORS策略是为了保证达到后端的请求绝对是可信的前端服务发起的,来避免一些跨站攻击。即使前端的异步请求成功发起了,浏览器也会依赖后端返回包的情况来进行可信情况的判断,通常情况下后端会加上这个header:
Access-Control-Allow-Origin: 可信的域名
通常来说前端发起异步请求时,浏览器就会进行一次域名本身的校验,发现是跨域之后就会阻止该异步请求发起,在咱们这个例子中就需要解决这个问题。
跨域的本身是避免非我方信任的请求,但是前端域名:https://www.a.com,后端域名:https://api.a.com:9000本就是我方信任的域名,所以通过一些手段绕过CORS也是合理的,但是也会增加一定的风险,后面会细讲。
解决方案
当前nodejs已经很强大了,可以算作一个全栈语言了,能搞前端能搞后端服务,咱们的方法也很简单,就是通过设置代理服务解决。
同域名的不同端口也是属于同域的,所以我们设置一个其他端口的代理,让请求发向这个同域的代理服务地址,这里属于同域的,不存在跨域的问题,然后再由代理发向后端,此时与浏览器就没有关系了。
流程如下:
那么,在node的项目中配置一个代理也很简单,在package.json中增加proxy参数:
{
...
"proxy": "后端地址"
}
如此,相当于把你自己配置代理的过程给省略了,直接挂上代理转发到后端的地址即可。但是,这样只解决了通过浏览器发出请求的问题。
浏览器发出请求后,还会校验后端配置的 Access-Control-Allow-Origin,来确保实际的前端发起域是否可信。
很多时候为了方便起见,大家都会把该参数配置成如下,来允许所有域
Access-Control-Allow-Origin: *
这就会造成一定的风险,即攻击者也可以通过类似的方法来绕过CORS策略进行信息获取。所以,建议这里尽量不要使用*,而是把把自己可信的域名给配上去。
例如在这个例子中,配置如下:
Access-Control-Allow-Origin: https://api.a.com:9000
收工!
原文始发于微信公众号(飞羽技术工坊):解决前后端分离架构下的不同域的跨域请求问题
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论