zoukankan      html  css  js  c++  java
  • 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("/**");
      
          }
      }
      
      
  • 相关阅读:
    中文字,文本框,button按钮垂直居中对齐方法
    Denny_Yang的语录
    为SELECT结果集添加伪序号列
    考勤系统问题记录一:事务日志太大
    在DateTable中进行数据统计(不用循环)
    今天去游泳了
    关于HbSrv.exe
    有感于--特洛伊
    windows下DNS的问题
    Google新功能
  • 原文地址:https://www.cnblogs.com/MonkeySun/p/13881933.html
Copyright © 2011-2022 走看看