springboot jwttoken ajax请求的时候跨域问题
1 跨域有2种
简单跨域和复杂跨域
复杂跨域比如header中加了Authorization token,复杂跨域时,浏览器会发出一个Optional的请求,先试探一下服务允许不允许。
都可以解决
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Autowired
AuthenticationFilter authenticationFilter;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticationFilter)
// .excludePathPatterns("/**")
.addPathPatterns("/vehicle/testToken")
// .addPathPatterns("/**")
// .addPathPatterns("/**")
// .excludePathPatterns("/login")
.excludePathPatterns("/swagger-resources/**", "/swagger-resources/configuration/ui", "/swagger-ui.html/**", "/v2/**",
"/login");;
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.allowedHeaders("*")
.maxAge(3600)
.allowCredentials(true);
}
}
以上addCrosMappings中的内容就同事可以解决简单跨域和复杂跨域。
但是关键坑爹的事情来了 通过跨域之后如果写了拦截器,验证token 那么由于optional请求中没有带token会在拦截器处被拦截 返回401,这对这个事情 有以下写法
@Component
public class AuthenticationFilter extends HandlerInterceptorAdapter {
@Autowired
JwtUtil jwtUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if ("OPTIONS".equals(request.getMethod())){//这里通过判断请求的方法,判断此次是否是预检请求,如果是,立即返回一个204状态吗,标示,允许跨域;预检后,正式请求,这个方法参数就是我们设置的post了
response.setStatus(HttpStatus.SC_NO_CONTENT); //HttpStatus.SC_NO_CONTENT = 204
response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS, DELETE");//当判定为预检请求后,设定允许请求的方法
response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, Token"); //当判定为预检请求后,设定允许请求的头部类型
response.addHeader("Access-Control-Max-Age", "1");
return true;
}
// 是否登录
boolean isLogin = false;
// 获取请求头 Authorization: Bearer jwtToken
final String authHeader = request.getHeader("Authorization");
// 判断是否有token,注意 Bearer 后面有空格
if (authHeader != null && authHeader.startsWith("Bearer ")) {
// 截取获取jwtToken
final String token = authHeader.substring(7);
// 解析
Claims claims = jwtUtil.parseJWT(token);
if (claims != null) {
if ((Boolean) claims.get("isLogin")) {
// 已登录
isLogin = true;
}
}
}
if(!isLogin) {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(401);
response.getWriter().write("未通过身份认证");
}
return isLogin;
}
}
这个写法第一 让optional请求不用经过拦截器被拦截,而且在resopnse中返回了需要的信息 比如允许跨域等 这就解决了问题

浙公网安备 33010602011771号