前后端分离下spring security 跨域问题等

    技术2022-07-12  64

    最近在做一个项目,前后端分离,不可避免的遇到了跨域问题。起初是配置跨域:

    @Configuration public class CorsConfig extends WebMvcConfigurerAdapter {     private CorsConfiguration buildConfig() {         CorsConfiguration corsConfiguration = new CorsConfiguration();         corsConfiguration.addAllowedOrigin("*");         corsConfiguration.addAllowedHeader("*");         corsConfiguration.addAllowedMethod("*");         corsConfiguration.addExposedHeader("Authorization");         return corsConfiguration;     }       @Bean     public CorsFilter corsFilter() {         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();         source.registerCorsConfiguration("/**", buildConfig());         return new CorsFilter(source);     }       @Override     public void addCorsMappings(CorsRegistry registry) {         registry.addMapping("/**")                 .allowedOrigins("*")                 .allowCredentials(true)                 .allowedMethods("GET", "POST", "DELETE", "PUT")                 .maxAge(3600);     } }

    在测试时发现在spring security下这些跨域配置并没有生效(被无视了。。。),依靠度娘挣扎测试了好久(整整一天,lz晚上睡觉都在想为啥为啥???),需要在springsecurity配置中加上cors()来开启跨域以及requestMatchers(CorsUtils::isPreFlightRequest).permitAll()来处理跨域请求中的preflight请求。

    //开启跨域 cors() http.cors().and().csrf().disable().authorizeRequests()          //处理跨域请求中的Preflight请求          .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()          .antMatchers(HttpMethod.GET,"/hello/hello").permitAll()          .antMatchers("/oauth/login").permitAll()          .anyRequest().authenticated()          .and()          .formLogin()          //自定义登录页面          .loginPage("/oauth/login")          .and()          .logout()          .and()          .addFilter(new JWTLoginFilter(authenticationManager()))          .addFilter(new JWTAuthenticationFilter(authenticationManager()));

    当jwt token无效过期等时请求将跳到你自定义的登录页面(默认是/login),基于前后端分离,我这里自定义了一个登陆请求,以restful风格返回给前端,前端可依据返回的code全局路由到真正的登录页面。

    跨域解决了,然后坑又来了,一堆的/oauth/login请求是什么鬼???陷入死循环了。。。当你的token无效时,他将继续带着token请求/oauth/login,在这个请求时,又要开始判断他的token,反反复复。。。

    所以,在token的校验中,当我们的请求是/oauth/login时,将请求放行

     String header = request.getHeader(JwtTokenUtils.TOKEN_HEADER);           String requestURI = request.getRequestURI();         // 如果请求头中没有Authorization信息则直接放行了         if(header == null || !header.startsWith(JwtTokenUtils.TOKEN_PREFIX) || requestURI.equals("/oauth/login")){             chain.doFilter(request,response);             return;         }

    测试:带着一个过期的token去访问/hello/getNews将定义到/oauth/login

    返回结果:

     

    Processed: 0.011, SQL: 9