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中返回了需要的信息 比如允许跨域等  这就解决了问题

posted @ 2021-01-08 15:00  当年在远方  阅读(379)  评论(1编辑  收藏  举报