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验证。

Spring Security 和 Vue.js 在处理问题时通常会遇到一些挑战,因为它们分别负责后台服务器的安全控制和前端应用的数据请求。Vue.js默认不支持请求,而Spring Security在默认情况下可能会限制来自不同源的HTTP访问。以下是解决这个问题的一些步骤: 1. **配置Spring Security**: - 如果Spring Security设置了CORS(源资源共享)策略,你需要确保允许特定的Origin。在WebSecurityConfigurerAdapter中添加如下的代码片段: ```java @Override public void configure(HttpSecurity http) throws Exception { http.cors().and() .authorizeRequests() // 允许特定的名 .antMatchers("/**").allowedOrigins("*") .anyRequest().authenticated(); // 更详细的设置可以在configureCors方法中完成 } ``` 2. **启用CORS预检请求**: - 当浏览器发起请求时,它首先发送一个OPTIONS请求(也称为"预检请求")。如果你的服务器没有响应这些请求,可能需要在Spring MVC或Filter层上处理这些预检请求。 3. **后端允许简单请求头**: - 在Spring Security中,你可以设置`corsConfiguration.addAllowedHeader("*")`来允许所有请求头,并`corsConfiguration.addAllowedMethod("*")`允许所有HTTP方法。 4. **Vue.js 中的处理**: - 在Vue项目中,当向非同源API发起AJAX请求时,你需要设置`withCredentials: true`,同时在axios的配置里处理: ```javascript axios.defaults.withCredentials = true; axios.interceptors.request.use(config => { if (window.isLocalhost) { config.headers.common['X-Custom-Header'] = 'your-value'; // 假设这里有个自定义header } return config; }, error => Promise.reject(error)); ``` 5. **Nginx、Apache等反向代理**: - 如果你是在生产环境中,可以考虑使用Nginx或Apache作为代理服务器,将请求转发到Spring Boot服务器,并在那里处理CORS设置。 记得测试每个解决方案是否有效,因为问题可能受多个因素影响。如果你的Spring Security配置了更复杂的策略,可能还需要根据具体情况进行调整。相关的相关问题:
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值