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/*");
    }
}

完毕

posted @ 2021-08-06 00:33  夏秋初  阅读(641)  评论(0编辑  收藏  举报