什么是同源策略 跨域
协议 url 端口 任一不同则不同源
例如 http://www.baidu.com 与https://www.baidu.com http://www.baidu.com:8080 http://www.taobao.com不同源
同源策略是浏览器的限制 如在www.baidu.com的网页下 去访问www.taobao.com 这样则形成了跨域 那么浏览器则会限制响应数据(注意 这里是指限制访问响应的数据 而不是限制访问),也就是拿不到响应的数据
同时 浏览器还限制了不是一个域 不能访问其它域下的cookies的内部数据
例如下图 csdn.net域下的页面脚本文件无法拿到baidu..com下的cookies信息
为什么要有同源策略呢
试想一下 如果浏览器没有同源策略 你访问一个支付网站(暂认为是支付宝)完成了你的转账,这时候你又访问了一个钓鱼网站 这个时候钓鱼网站页面向支付宝网站请求了一个获取你敏感信息的接口 这个时候你的数据就会外泄
如果在开发中需要跨域那么怎么解决呢
方案一:利用nginx将前端页面与后端服务都通过80端口反向代理访问
方案二:后端进行跨域配置
1.使用@CrossOrigin注解标注的接口都可以跨域请求
@GetMapping("/list")
@CrossOrigin
public List<String> list(){
List<String> list = Arrays.asList("Java");
return list;
}
2.使用过滤器
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter(){
CorsConfiguration corsConfiguration = new CorsConfiguration();
//配置可以跨域的访问源地址
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
3 实现 WebMvcConfigurer 接口,重写 addCorsMappings 方法
@Configuration
public class CorsConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")//允许哪些域访问
.allowedMethods("GET","POST","PUT","DELETE","HEAD","OPTIONS")//允许哪些方法访问
.allowCredentials(true)//是否允许携带cookie
.maxAge(3600)//设置浏览器询问的有效期
.allowedHeaders("*");//
}
}
那么 上述解决方案是怎么解决跨域的呢
其实就是服务器在响应客户端的时候会在响应头加上一行
Access-Control-Allow-Origin: http://www.acceptmeplease.com
这样 如果当前网站的源与响应头中的源相同 那么浏览器则则可以操作响应的数据啦 就不会造成跨域了
另外 如果是get之外的请求跨域了 那么浏览器还会先发送一个请求询问服务器 你这个接口支持跨域吗 这个时候服务器告诉它 支持 这个时候才能发起实际的请求
参考资料如下
csrf攻击(跨站伪造请求攻击)
什么是csrf攻击呢,还是拿上面的例子举例
你访问一个支付网站(暂认为是支付宝)完成了你的转账,这时候你又访问了一个钓鱼网站 这个时候钓鱼网站页面向支付宝网站请求了一个转账接口转账给钓鱼网站的账户 这个时候浏览器会默认带上支付宝的cookies 假设支付宝没有防止csrf攻击 这个时候便转账成功了
那么如何防止csrf攻击呢
方案一:每次请求都需要验证码,csrf攻击只是伪造请求 它并不能识别需要填的验证码 所以如果每一次请求都需要填验证码 csrf攻击自然无效了 但是 这种方案肯定会极大的影响用户体验
方案二:还记得上文提到的不同源无法对cookie里面的数据进行操作访问吗,也就是说不同源拿不到你cookie里面的信息 那么 为了防止csrf攻击 我们可以让前端把cookie中写入的token放到请求头中 每次请求都带过来 然后服务端再对请求头里面的token进行校验 因为不同源 钓鱼网站拿不到支付宝的cookie里的信息 那么钓鱼网站自然不能在请求头上加token 这样也很完美的解决了csrf攻击!