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

https://blog.csdn.net/Box_clf/article/details/80973391

主要问题:针对前后端分离后,前端使用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验证。
--------------------- 
作者:Box_clf 
来源:CSDN 
原文:https://blog.csdn.net/Box_clf/article/details/80973391 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值