Java拦截器HandlerInterceptor重写preHandle方法时HttpServletRequest无法获取自定义请求头参数问题

Posted Acmen-zym

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java拦截器HandlerInterceptor重写preHandle方法时HttpServletRequest无法获取自定义请求头参数问题相关的知识,希望对你有一定的参考价值。

问题描述

在前端vue中设置的自定义请求头参数:token

控制层可以正常获取到自定义请求头参数

拦截器中无法获取

下方是拦截器代码

@Component
public class JWTInterceptor implements HandlerInterceptor 
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private AdminUserAuthRedis userAuthRedis;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception 
        String token = request.getHeader("token");
        //验证token是否有效
        boolean verifyUserAuthToken = userAuthRedis.verifyUserAuthToken(token);
        if (!verifyUserAuthToken) 
            MvcCodeStatusEnum expireLogin = MvcCodeStatusEnum.EXPIRE_LOGIN;
            response.sendError(expireLogin.getCode(), expireLogin.getMessage());
            response.setStatus(expireLogin.getCode());
            return false;
        
        //用户访问路径验证
        boolean verifyUserAccessPaths = verifyUserAccessPaths(request, token);
        if (!verifyUserAccessPaths) 
            MvcCodeStatusEnum expireLogin = MvcCodeStatusEnum.ACCESS_NO_PERMISSION;
            response.sendError(expireLogin.getCode(), expireLogin.getMessage());
            response.setStatus(expireLogin.getCode());
            return false;
        
        return true;
    

    /**
     * 检测用户是否有当前访问路径
     *
     * @param request 服务请求
     * @param token   用户登陆到token
     * @return 有权限则返回true
     */
    private boolean verifyUserAccessPaths(HttpServletRequest request, String token) 
        Set<String> userAccessPaths = userAuthRedis.getUserAccessPaths(token);
        if (CollectionUtils.isEmpty(userAccessPaths)) 
            logger.info("无法获取用户授权路径,请重新授权Token");
            userAuthRedis.clearLoginInfo(token);//路径验证不通过,需要重新登陆授权
            return false;
        
        String path = request.getServletPath();
        String lowerCase = System.getProperty("os.name").toLowerCase();
//        if (lowerCase.startsWith("win")) 
//            logger.info("本地环境: 暂时忽略权限校验!", path);
//            return true;
//        
        if (!StringUtils.isEmpty(path)) 
            // 去掉一层前缀后进行校验
            int index = path.indexOf("/", 1);
            if (index != -1) 
                String substring = path.substring(index + 1);
                if (substring.startsWith("ignore")) 
                    logger.info("接口路径: 权限校验忽略!", path);
                    return true;
                
            
        
        boolean anyMatch = userAccessPaths.stream().filter(x -> !StringUtils.isEmpty(x)).anyMatch(path::endsWith);
        if (!anyMatch) logger.info("暂未授权的路径 path:", path);
        return anyMatch;
    

解决方案

在注册拦截器配置的时候加上自定义参数名在allowedHeaders中加上token参数名,并且对OPTIONS请求放行

@Configuration
public class AccessSecurityConfig implements WebMvcConfigurer 

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private JWTInterceptor jwtInterceptor;

    @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**")
                .allowCredentials(false)
                .allowedMethods("POST", "GET", "DELETE", "PUT", "OPTIONS")
                .allowedHeaders("token")
                .allowedOrigins("*");
    
 

以上是关于Java拦截器HandlerInterceptor重写preHandle方法时HttpServletRequest无法获取自定义请求头参数问题的主要内容,如果未能解决你的问题,请参考以下文章

java handlerinterceptor 切面哪个先执行

HandlerInterceptor与MethodInterceptor

如何使多个 Spring HandlerInterceptor 以特定顺序执行

Spring MVC学习—HandlerInterceptor处理器拦截器机制全解

[十四]SpringBoot 之 Spring拦截器(HandlerInterceptor)

SpringMVC之HandlerInterceptor拦截器详解