CORS 简介
为了解决浏览器同源问题,W3C
提出了跨源资源共享,即 CORS
(Cross-Origin Resource Sharing)。
CORS
做到了如下两点:
- 不破坏即有规则
- 服务器实现了
CORS
接口,就可以跨源通信
Access-Control-Allow-Origin:
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000
他们的含义分别是:
- Access-Control-Allow-Methods: 真实请求允许的方法
- Access-Control-Allow-Headers: 服务器允许使用的字段
- Access-Control-Allow-Credentials: 是否允许用户发送、处理 cookie
- Access-Control-Max-Age: 预检请求的有效期,单位为秒。有效期内,不会重复发送预检请求
当预检请求通过后,浏览器会发送真实请求到服务器。这就实现了跨源请求。
Springboot解决跨域
(全局跨域)
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsFilter corsFilter() {
//1.添加CORS配置信息
CorsConfiguration config =new CorsConfiguration();
//放行哪些原始域
("*");
//是否发送Cookie信息
(true);
//放行哪些原始域(请求方式)
("*");
//放行哪些原始域(头部信息
("*");
//暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
("*");
//2.添加映射路径
UrlBasedCorsConfigurationSource configSource =new UrlBasedCorsConfigurationSource();
("/**", config);
//3.返回新的CorsFilter.
return new CorsFilter(configSource);
}
}
2.重写WebMvcConfigurer(全局跨域)
//springboot 1.5方式
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
("/**").allowedHeaders("*")
.allowedMethods("*")
.allowedOrigins("*")
.allowCredentials(true);
}
}
//springboot 2.0以上的方式
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
("/**")
.allowedHeaders("Content-Type","X-Requested-With","accept,Origin","Access-Control-Request-Method","Access-Control-Request-Headers","token")
.allowedMethods("*")
.allowedOrigins("*")
.allowCredentials(true);
}
}
3.使用注解@CrossOrigin(局部跨域)
@CrossOrigin源码
@Target({ , })
@Retention()
@Documented
public @interface CrossOrigin {
String[] DEFAULT_ORIGINS = { "*" };
String[] DEFAULT_ALLOWED_HEADERS = { "*" };
boolean DEFAULT_ALLOW_CREDENTIALS = true;
long DEFAULT_MAX_AGE = 1800;
/**
* 同origins属性一样
*/
@AliasFor("origins")
String[] value() default {};
/**
* 所有支持域的集合,例如""。
* <p>这些值都显示在请求头中的Access-Control-Allow-Origin
* "*"代表所有域的请求都支持
* <p>如果没有定义,所有请求的域都支持
* @see #value
*/
@AliasFor("value")
String[] origins() default {};
/**
* 允许请求头重的header,默认都支持
*/
String[] allowedHeaders() default {};
/**
* 响应头中允许访问的header,默认为空
*/
String[] exposedHeaders() default {};
/**
* 请求支持的方法,例如"{, }"}。
* 默认支持RequestMapping中设置的方法
*/
RequestMethod[] methods() default {};
/**
* 是否允许cookie随请求发送,使用时必须指定具体的域
*/
String allowCredentials() default "";
/**
* 预请求的结果的有效期,默认30分钟
*/
long maxAge() default -1;
}
Spring security 跨域问题
使用上面方法在继承spring security时可以会出现失效的情况,解决办法如下,根据情况使用
方式1
SecurityConfig中配置开启CORS
@Override
protected void configure(HttpSecurity http) throws Exception {
// 允许跨域访问
();
}
默认会找name为corsConfigurationSource的bean
@Bean
pubilc CorsConfigurationSource CorsConfigurationSource() {
CorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
("*"); //同源配置,*表示任何请求都视为同源,若需指定ip和端口可以改为如“localhost:8080”,多个以“,”分隔;
("*");//header,允许哪些header,本案中使用的是token,此处可将*替换为token;
("*"); //允许的请求方法,PSOT、GET等
((UrlBasedCorsConfigurationSource) source).registerCorsConfiguration("/**",corsConfiguration); //配置允许跨域访问的url
return source;
}
方式2
使用spring security以前版本没有,在security配置中新增过滤器,注意过滤器顺序
(customCorsFilter, );
customCorsFilter为过滤器,使用spring boot中第一种解决方案的过滤器即可
spring secret:/spring-security/site/docs