在前后端分离开发条件下,几乎一定会遇到跨域问题。
同源策略
浏览器安全的基石是 同源策略,什么是同源策略呢?
- 协议相同。
- 域名相同。
- 端口相同。
同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。
如果两个 URL 的 protocol、port (en-US) (如果有指定的话) 和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是“元组”。(“元组”是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。
所谓“同源”就是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
下表给出了与 URL http://store.company.com/dir/page.html
的源进行对比的示例:
URL | 结果 | 原因 |
http://store.company.com/dir2/other.html |
同源 | 只有路径不同 |
http://store.company.com/dir/inner/another.html |
同源 | 只有路径不同 |
https://store.company.com/secure.html |
失败 | 协议不同 |
http://store.company.com:81/dir/etc.html |
失败 | 端口不同 ( http:// 默认端口是 80) |
http://news.company.com/dir/other.html |
失败 | 主机不同 |
为什么要做这个同源的限制
1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
这个过程就是著名的CSRF(Cross Site Request Forgery),跨站请求伪造,正是由于可能存在的伪造请求,导致了浏览器的不安全。
同源策略限制哪些行为
同源策略是一个安全机制,他本质是限制了从一个源加载的文档或脚本如何与来自另一个源的资源进行交互,这是一个用于隔离潜在恶意文件的重要安全机制。
- Cookie、LocalStorage 和 IndexDB 无法读取。
- DOM 无法获得。
- AJAX 请求不能发送。
CORS实现机制
跨域资源共享(CORS
)是一种机制,是W3C标准。它允许浏览器向跨源服务器,发XMLHttpRequest
或Fetch
请求。并且整个CORS
通信过程都是浏览器自动完成的,不需要用户参与。
而使用这种跨域资源共享
的前提是,浏览器必须支持这个功能,并且服务器端也必须同意这种"跨域"
请求。因此实现CORS
的关键是服务器需要服务器。通常是有以下几个配置:
1. Access-Control-Allow-Origin 2. Access-Control-Allow-Methods 3. Access-Control-Allow-Headers 4. Access-Control-Allow-Credentials 5. Access-Control-Max-Age
springboot设置cors
springboot设置cors的的本质都是通过设置响应头信息来告诉前端该请求是否支持跨域。
springboot设置cors的方式主要有以下三种。
1. 配置过滤器corsfilter
1. @configuration 2. public class corsconfig { 3. 4. @bean 5. corsfilter corsfilter() { 6. corsconfiguration configuration = new corsconfiguration(); 7. configuration.setallowedorigins(arrays.aslist("*")); 8. configuration.setallowedmethods(arrays.aslist("*")); 9. configuration.setallowedheaders(arrays.aslist("*")); 10. configuration.setallowcredentials(true); 11. urlbasedcorsconfigurationsource source = new urlbasedcorsconfigurationsource(); 12. source.registercorsconfiguration("/**", configuration); 13. return new corsfilter(source); 14. } 15. }
2. 实现接口webmvcconfigurer
1. @configuration 2. public class webmvcconfig implements webmvcconfigurer { 3. 4. @override 5. public void addcorsmappings(corsregistry registry) { 6. registry.addmapping("/**") 7. .allowedorigins("*") 8. .allowedheaders("*") 9. .allowedmethods("*") 10. .allowcredentials(true); 11. } 12. }
3. 使用注解@crossorigin
@crossorigin注解可以用在类或者方法上
用在控制器类上,表示 该类的所有方法都允许跨域
1. @restcontroller 2. @crossorigin 3. public class testcontroller { 4. 5. @getmapping("test") 6. public string test() { 7. return "success"; 8. } 9. }