前后端分离的项目中,后端filter使用response遇到的跨域问题如何解决?

项目大致情况:后端采用RESTful Api,spring boot+spring security+JWT,前端vue全家桶。

部署情况:前端放在nginx里,开了个8088端口,后端jar包运行在8080端口

关于跨域问题解决的七七八八了,但是唯独这个filter的跨域问题解决不了。在spring security的filter中通过response返回信息前端是接收不到的,chrome浏览器也不会显示请求的任何返回,我查了好久才反映过来可能是跨域问题。

需求就是当token失效时,请求接口会通过filter,如果filter判断出token失效,则直接通过response返回一个约定的状态码。如果在这里不返回,服务器直接报500,前端不方便捕捉处理。filter里,请求头可以通过Access-Control-Expose-Headers写进去,前端也能捕获到,请求体怎么办呢?求大神赐教。

目前这样处理是得不到请求体的,其中一个filter的代码:
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
    String authHeader = httpServletRequest.getHeader("Authorization");
    if (authHeader != null && authHeader.startsWith("Bearer ")) {
        final String authToken = authHeader.substring("Bearer ".length());
        try {
            String newToken = JwtUtil.refreshToken(authToken);
            if (newToken != null) {
                httpServletResponse.setHeader("authentication", newToken);
            }
        } catch (JwtException e) {
            log.error(e.toString());
            httpServletResponse.getWriter().write(JSON.toJSONString(Result.failure("无效的token,请重新登陆后操作")));
            return;
        }
        String username;
        try {
            username = JwtUtil.parseToken(authToken);
        } catch (JwtException e) {
            log.error(e.toString());
            httpServletResponse.getWriter().write(JSON.toJSONString(Result.failure("无效的token,请重新登陆后操作")));
            return;
        }
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = sysUserDetailsService.loadUserByUsername(username);
            if (userDetails != null) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
    }
    filterChain.doFilter(httpServletRequest,httpServletResponse);
阅读 4.7k
3 个回答
  • **XXXApplication.java** 中加入以下 Bean
    /**
     * 跨域问题
     * @return
     */
    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); 
//        config.addAllowedOrigin("http://localhost:9000");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config); // CORS 配置对所有接口都有效
        
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source) );
        bean.setOrder(0);
        return bean;
    }

response.setContentType("application/json; charset=utf-8");

新手上路,请多包涵

response.setHeader("Access-Control-Allow-Origin", "*");
跟你的corsFilter做的事一样 让跨域请求通过就行了。
我跟你一样的问题 加了这句就好了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题