2019独角兽企业重金招聘Python工程师标准>>>
项目采用前后端分离,服务器端添加了全局的跨域配置,但是却出现了跨域问题,分析了多次请求发现有一部分请求并没有出现跨域,没有出现跨域的请求刚好就是拦截器放行的地址,所以分析可能是权限拦截器处理在跨域处理之前进行导致跨域配置失效。
刚开始的跨域配置,继承WebMvcConfigurer 类重写addCorsMappings方法:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private TokenInterceptor tokenInterceptor;
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false);
}
/**
* 拦截器配置
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 需要排除的地址
String[] excludePath = {
// 注册登录
"/user/openId",
"/user/register",
"/user/login",
"/user/loginByOpenId",
"/user/updatePassword",
// 手机短信
"/phone/**",
"/hospital/get/**",
// 微信支付成功回调
"/order/callback/**",
// 服务号接口
"/serve/**",
// im群消息回调
"/im/callback/**",
// 测试地址
"/test/**",
// 手机号白名单
"/demoPhone/**",
// 错误页面
"/error/**",
// 带后缀的静态资源
"/**/**.*"
};
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(excludePath)
.excludePathPatterns();
}
/**
* 跨越配置
*
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置允许跨域的路径
registry.addMapping("/**")
// 是否允许证书 不再默认开启
.allowCredentials(true)
// 允许任何头
.allowedHeaders("*")
// 设置允许跨域请求的域名
.allowedOrigins("*")
// 设置允许的方法
.allowedMethods("*")
// 跨域允许时间
.maxAge(3600)
.exposedHeaders("token");
}
}
改用过滤器CorsFilter 来配置跨域,由于Filter的位置是在Interceptor之前的(Filter之间通过order设置优先级),问题得到解决:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private TokenInterceptor tokenInterceptor;
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false);
}
/**
* 拦截器配置
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 需要排除的地址
String[] excludePath = {
// 注册登录
"/user/openId",
"/user/register",
"/user/login",
"/user/loginByOpenId",
"/user/updatePassword",
// 手机短信
"/phone/**",
"/hospital/get/**",
// 微信支付成功回调
"/order/callback/**",
// 服务号接口
"/serve/**",
// im群消息回调
"/im/callback/**",
// 测试地址
"/test/**",
// 手机号白名单
"/demoPhone/**",
// 错误页面
"/error/**",
// 带后缀的静态资源
"/**/**.*",
"/followup/**/**.*",
"/imageControlWX/**/**.*",
"/pc/**/**.*",
"/qrcode/**/**.*",
"/recipe/**/**.*",
"/writeRecipe/**/**.*"
};
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(excludePath)
.excludePathPatterns();
}
/**
* 跨越配置
*/
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// 设置允许跨域请求的域名
config.addAllowedOrigin("*");
// 是否允许证书 不再默认开启
// config.setAllowCredentials(true);
// 设置允许的方法
config.addAllowedMethod("*");
// 允许任何头
config.addAllowedHeader("*");
config.addExposedHeader("token");
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
return new CorsFilter(configSource);
}
}