• Springboot2.3.5 实现JWT授权验证并针对不同用户实现多个拦截器


    参考

    1. Spring Boot 拦截器无效,不起作用
    2. 拦截器不生效
    3. SpringBoot 多个拦截器配置
    4. SpringBoot系列(十一)拦截器与拦截器链的配置与使用详解,你知道多少?
    5. Spring Boot教程:SpringBoot整合JWT
    6. Spring HandlerInterceptor与HandlerInterceptorAdapter
    7. SpringBoot之Filter/HandlerInterceptor 中注入service为null解决方案

    注意

    如果你的拦截器不生效,检查一下拦截规则,比如拦截 student/所有,配置相对拦截规则就是 /student/**

            /**
             * 学生拦截器
             */
            registry.addInterceptor(new JWTStudentInterceptor())
                    /**
                     * 拦截的路径,路径匹配规则要注意,匹配所有是 ** ,而不是一个 *
                     */
                    .addPathPatterns("/student/**")
                    /**
                     * 排除登录接口
                     */
                    .excludePathPatterns("/student/v1/auth/**","/student/v1/register/**");
    

    正文

    1. pom.xml 文件新增jwt扩展
    <!--        引入jwt-->
            <!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
            <dependency>
                <groupId>com.auth0</groupId>
                <artifactId>java-jwt</artifactId>
                <version>3.18.1</version>
            </dependency>
    
    
    1. 创建jwt工具类,Student是学生实体,因为本项目存在多种用户 老师、学生,所以就给他们区分开获取token以及验证token的方法。
    /**
     * @Author 夏秋初
     * @Date 2021/8/5 22:45
     * 参考:
     * https://blog.csdn.net/weixin_42654295/article/details/109280627
     * https://blog.csdn.net/qq_37059838/article/details/87859810
     */
    public class JWTUtils {
        /**
         * 默认令牌过期时间7天
         */
        public static  String getStudentToken(Student student){
            Calendar instance = Calendar.getInstance();
            instance.add(Calendar.DATE,7);
            JWTCreator.Builder builder = JWT.create();
            // 储存用户id,可以储存多个参数
            builder.withClaim("studentId",student.getId());
           // 可以通过  JWT.decode(token).getClaim("储存时候的key"),进行获取
           // builder.withClaim("studentId",student.getName());
            // 通过账号确认唯一
            String token = builder.withExpiresAt(instance.getTime())
                    .sign(Algorithm.HMAC256(student.getAccount()));
            return token;
        }
        /**
         * 验证token合法性 成功返回token
         * @param token
         * @return
         */
        public static DecodedJWT verifyStudentToken(String token, String account){
            JWTVerifier build = JWT.require(Algorithm.HMAC256(account)).build();
            return build.verify(token);
        }
        /**
         * 解密jwt
         */
        public static DecodedJWT decodeJWT(String token){
            return JWT.decode(token);
        }
    }
    
    1. 控制器内调用,即可获取jwt字符串
    JWTUtils.getStudentToken(student)
    
    1. interceptor/新增自定义拦截器,因为有多种用户,这里的拦截器针对学生的
    @Component
    # 这里注意 使用HandlerInterceptor 会导致@Autowired获取不到service
    # public class JWTStudentInterceptor implements HandlerInterceptor {
    public class JWTStudentInterceptor extends HandlerInterceptorAdapter {
    
        @Autowired
        StudentService studentService;
    
        @Override
        public  boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("进入JWT拦截器了");
            String token = request.getHeader("JWT");
            DecodedJWT decodeJWT = JWTUtils.decodeJWT(token);
            Integer id = decodeJWT.getClaim("studentId").asInt();
            Student student = studentService.findById(id);
            try {
                JWTUtils.verifyStudentToken(token, student.getAccount());
            }catch (Exception e){
                System.out.println("token无效");
                return false;
            }
            return true;
        }
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
            //
            System.out.println("JWT 执行完了");
        }
    
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            System.out.println("我获取到了一个返回的结果:"+response);
            System.out.println("请求结束了");
        }
    }
    
    1. config/创建拦截器配置类,并注册拦截器实现拦截
    @Configuration
    public class IntercaptorConfig  implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            /**
             * 学生拦截器
             */
            registry.addInterceptor(new JWTStudentInterceptor())
                    /**
                     * 拦截的路径
                     */
                    .addPathPatterns("/student/**")
                    /**
                     * 排除登录接口
                     */
                    .excludePathPatterns("/student/v1/auth/**","/student/v1/register/**");
            /**
             * 测试多个拦截器
             */
    //        registry.addInterceptor(new TestStudentInterceptor())
    //                /**
    //                 * 拦截的路径
    //                 */
    //                .addPathPatterns("/test/*");
        }
    }
    
    

    完毕

    如果觉得文章对您有帮助,希望您能 关注+推荐 哦
  • 相关阅读:
    STL++?pb_ds平板电视初步探索
    STL二分查找函数的应用
    线性DP LIS浅谈
    Manacher算法(马拉车算法)浅谈
    KMP瞎扯一下
    2018/11/9 周五集训队第四次测试赛补题题解
    洛谷P1294 高手去散步
    差分数组浅谈
    树状数组浅谈
    plugins标签:分页助手PageHelper的实现
  • 原文地址:https://www.cnblogs.com/xiaqiuchu/p/15106720.html
Copyright © 2020-2023  润新知