SpringBoot自定义注解拦截器,实现登录token验证

在写项目的过程中,如果使用filter的方式进行登录token验证,需要添加大量的过滤路径,每次添加新的接口后都要添加一次需要放行的接口,由此,使用拦截器+反射的机制拦截请求,判断是否需要放行

  1. 自定义注解,拦截Controller方法

    @Documented
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface FilterFrom {
        //默认是拦截的,添加注解后放行
     boolean value() default false;
    }
    
    
  2. 实现HandlerInterceptor接口 重写preHandle方法

@Override
    public  boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //拦截获取添加在适配器上的注解,判断是否有添加的放行注解
        HandlerMethod method = (HandlerMethod) handler;

        FilterFrom filterFrom = method.getMethodAnnotation(FilterFrom.class);

        /**
         * 添加了filterfrom注解就进行登录验证
         *
         *
         * 请求的方法可以有注解,也可以没有,有注解的情况下,进行判断值,如果是没注解的情况下呢,默认			拦截?
         *  没注解就直接拦截,禁止请求。
         *      解决办法:(自定义一个方法,返回boolean方法,获取token的方法。)
         */

        //获取添加在方法上的注解,判断是否存在放行注解
        if (filterFrom != null) {
            //如果设置放行注解为true,就直接放行
            if (filterFrom.value() == true) {
                return true;
            } else {
                return doFilter(request, response);
            }
        }
        //没添加注解,进行返回提示
        return noDoFilter(request, response);
    }

    public static boolean doFilter(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        //默认为false,拦截获取token
        String token = null;
        try {
            token = request.getHeader(SystemConfig.TOKEN_HEADER);
        } catch (NullPointerException e) {
            e.printStackTrace();
        }

        if (StrUtil.checkNoEmpty(token)) {
			//获取redis中token的key
            String key = RedisKeyConfig.LOGIN_TOKEN + token;
            //获取redis中token的key储存的value
            String user = JedisUtil.getInstance().STRINGS.get(key);

            if (user != null) {
                //请求进来就刷新一次token的有效期
                JedisUtil.getInstance().expire(key, RedisKeyConfig.LOGIN_TIME);
                JedisUtil.getInstance().expire(RedisKeyConfig.LOGIN_USER +
                        new JSONObject(user).getInt("id"), RedisKeyConfig.LOGIN_TIME);
                return true;
            } else {
                response.getWriter().print(new JSONObject(R.fail("登录有效期已过,请重新登陆")));
                return false;
            }
        } else {
            response.getWriter().print(new JSONObject(R.fail("您还没有登录,请登陆")));
            return false;
        }
    }

    public static boolean noDoFilter(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().print(new JSONObject(R.fail("您还没有登录,请登陆")));
        return false;
    }
  1. 创建拦截器配置类实现WebMvcConfigurer,添加自定义注解

    @Configuration
    public class InterceptorConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //注解拦截器
            registry.addInterceptor(new InterceptorUtil()).addPathPatterns("/**");
    
        }
    }
    
    
posted @ 2020-10-26 22:45  筋肉猩  阅读(4381)  评论(0编辑  收藏  举报