SpringSecurity使用JWT与前端交互跨域解决后端获取header中的Authorization的token值 - Go语言中文社区

SpringSecurity使用JWT与前端交互跨域解决后端获取header中的Authorization的token值


主要问题:针对前后端分离后,前端使用ajax进行请求,存在一些跨域的问题。

后端对跨域的问题进行解决,因为我是使用的Springboot框架做的后端,首先解决普通请求跨域的问题

@CrossOrigin

每一个controller类上需要添加CrossOrigin的注解进行处理。

添加之后在使用SpringSecurity时允许匿名访问的接口都没有跨域的问题了,不过使用JWT对用户身份进行验证时虽然前端已经将token的值添加到了header中,还是值获取不到header中的token值。

关键的问题就是在这里:

    浏览器会在ajax发送请求之前发送一个预请求,确认当请的接口是不是有效的接口,此时的请求方式是OPTIONS的请求方式


因为之前一直没有判断是否是预请求,所以security直接将请求的方式做了正常的处理,导致没有获取到token值所以返回的相应一直是401未授权。这时候就看到前端即使是在头部添加了token但是请求接口一直提示身份认证失败。

需要更改JWT过滤器中的对前端请求的处理方式:

@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    //定义的tokenHeader的名称
    private String tokenHeader = "Authorization";

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        if (request.getMethod().equals("OPTIONS")){
            log.info("浏览器的预请求的处理..");
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS,DELETE");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Authorization,token");
            return;
        }else {
            String authToken = request.getHeader(this.tokenHeader);

            String username = jwtTokenUtil.getUsernameFromToken(authToken);

            log.info("checking authentication for user " + username);

            //token中的username不为空是进行验证token是否是有效的token
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                log.info("token中的username不为空,Context中的authentication为空时,进行token的验证..");
                //TODO,从数据库得到带有密码的完整user信息
                   UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
                log.info("加载userdetails:{}",userDetails.getUsername());
                // For simple validation it is completely sufficient to just check the token integrity. You don't have to call
                // the database compellingly. Again it's up to you ;)
                if (jwtTokenUtil.validateToken(authToken, userDetails)) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    log.info("authenticated user " + username + ", setting security context");
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }

            chain.doFilter(request, response);
        }


    }
}

对第一次的请求进行判断是否是OPTIONS的请求方式,如果是则在对应的response中添加对跨域和header的配置信息

            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS,DELETE");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Authorization,token");

如果不是则进行后面的token验证。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/Box_clf/article/details/80973391
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 22:07:02
  • 阅读 ( 977 )
  • 分类:前端

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢