自制jwt注解 | 青训营

84 阅读3分钟

介绍

平时我们在开发项目的时候,总是需要用到jwt去协助我们进行权限校验,那么我们就得去配置jwt相关的东西,本人认为可以将配置jwt的这个过程进行简化,同时,只对用jwt注解标记了的方法才进行token校验,方便我们的日常开发。

代码准备

pom

此处要导入jjwt,此依赖会给我们提供jwt的相关方法,帮助我们生成token

<dependencies>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

自定义jwt工具类

提前封装好对应的生成token和校验token的方法,方便我们后续的开发

public class JwtUtil {
    public static String createToken(String username, int id){
        Map<String, Object> headMap = new HashMap();
        headMap.put("alg", SignatureAlgorithm.HS256.getValue());//使用HS256签名算法
        headMap.put("typ", "JWT");

        Map body = new HashMap();
        body.put("username",username);
        body.put("id",id);

        String jwt = Jwts.builder()
                .setHeader(headMap)
                .setClaims(body)
                .setId("jwt001")
                .signWith(SignatureAlgorithm.HS256,"chen")
                .compact();
        return jwt;
    }

    public static Map parseToken(String token){
        try{
            Jwt result = Jwts.parser().setSigningKey("chen").parse(token);
            Object jwtBody = result.getBody();
            return (Map<String, Object>) jwtBody;
        }catch (Exception e) {
            return null;
        }
    }
}

annotation

此处新建我们想要定义的注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JWT {
    String desc() default "添加此注解的方法会经过jwt校验";
}

JwtInterceptor

我们可以用aop对用@JWT注解标记的方法进行增强 这段代码是一个拦截器,用于进行 JWT校验。下面是代码的功能概述:

  1. 当请求到达时,preHandle 方法会被调用。
  2. 通过获取被拦截的方法对象和方法上的注解,判断是否需要进行 JWT 校验。
  3. 如果方法上加了 JWT 注解,则需要进行 JWT 校验。
  4. 执行 JWT 校验的逻辑,包括解析请求头中的授权信息,验证 JWT 的有效性。
  5. 如果 JWT 校验通过,输出认证通过的信息,并返回 true,说明执行后续的业务代码。
  6. 如果 JWT 校验失败,返回错误信息,并设置响应状态为 403,返回 false,说明不允许执行后续的业务代码。

总之,这段代码的作用是在请求到达时,根据方法上的 JWT 注解进行 JWT 校验,确保请求的合法性和安全性。

public class JwtInterceptor extends HandlerInterceptorAdapter {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        Method method = handlerMethod.getMethod();//获得被拦截的方法对象
        JWT jwt = method.getAnnotation(JWT.class);//获得方法上的注解
        if(jwt != null){
            //方法上加了jwt注解,需要进行jwt校验
            System.out.println("开始执行jwt校验");
            String auth = request.getHeader("authorization");
            Map map = JwtUtil.parseToken(auth);
            if(map != null){
                System.out.println("认证通过");
                System.out.println(map.get("username"));
                System.out.println(map.get("id"));
                return true;
            }
            response.getWriter().println("failed");
            response.setStatus(403);
            return false;
        }
        return true;
    }
}

添加配置类

这个类是一个配置类,实现了WebMvcConfigurer接口。

addInterceptors 方法 - 这个方法用于将拦截器添加到拦截器注册表中。在这里,它添加了一个 JwtInterceptor 实例。

@Configuration
public class JwtConfiguration implements WebMvcConfigurer {
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JwtInterceptor());
    }
}

测试

@RestController
@RequestMapping("/users")
public class UserController {
    @JWT
    @GetMapping
    public String login(){
        System.out.println(JwtUtil.createToken("admin", 1));
        return "succeed";
    }
}

在这个代码中,login方法被加上了@JWT注解,这个方法就会被得到增强,每次调用此接口的时候,程序都会校验一次token。