JWT —— 使用与封装


1、JWT的组成结构

JWT由三部分组成:

  1. 标头(header)
  2. 有效载荷(payload)
  3. 签名(signature)

1.1、header

header 由两部分组成:令牌的类型(JWT)和签名所使用的算法。它使用 Base64 编码组成

注意:Base64 不是加密算法,所以 header 是没有加密的

1.2、payload

payload 用来存放实际需要传递的数据,同样使用 Base64 编码组成

JWT 规定了7个官方字段:

  • iss(issuer):签发人
  • exp(expiration time):过期时间
  • sub(subject):主题
  • aud(audience):受众
  • nbf(Not Before):生效时间
  • iat(Issued At):签发时间
  • jti(JWT ID):编号

其他数据使用 withClain 存放

注意:Base64 不是加密算法,所以 header 是没有加密的,不建议放敏感信息

1.3、signature

signature 使用编码后的 header 和 payload 以及一个密钥,使用指定的加密算法进行加密。

签名的作用是保证 JWT 没有被篡改过

2、引入依赖

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.1</version>
</dependency>

3、JWT的使用

3.1、生成Token

Calendar instance = Calendar.getInstance();
instance.add(Calendar.MINUTE, 2);
// 生成令牌
String token = JWT.create()
        .withClaim("userId", 123) // payload
        .withClaim("username", "张三")
        .withExpiresAt(instance.getTime()) // 过期时间
        .sign(Algorithm.HMAC256("dasjj126341")); // 加密算法及密钥

3.2、解析Token

JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("dasjj126341")).build();

DecodedJWT verify = jwtVerifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzA5MTQ5ODEsInVzZXJJZCI6MTIzLCJ1c2VybmFtZSI6IuW8oOS4iSJ9.8DB2zK7nMGCRrPNqSlvRmH8vKdhTvFFbfHMgCVlZWo8");

System.out.println(verify.getClaim("userId"));
System.out.println(verify.getClaim("username"));

3.3、常见异常信息

- SignatureVerificationException:  签名不一致异常
- TokenExpiredException:           令牌过期异常
- AlgorithmMismatchException:      算法不匹配异常
- InvalidClaimException:           失效的payload异常

4、封装工具类

public class JWTUtils {

    /**
     * 密钥
     */
    private static final String SIGN = "ju!aSWWd23@4";

    /**
     * @param map : 写入payload中的数据
     * @return : token
     */
    public static String getToken(Map<String, String> map) {
        // 默认7天
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE, 7);

        // payload
        JWTCreator.Builder tokenBuilder = JWT.create();
        map.forEach(tokenBuilder::withClaim);

        tokenBuilder.withExpiresAt(instance.getTime());
        return tokenBuilder.sign(Algorithm.HMAC256(SIGN));
    }

    /**
     * @param map : 写入payload中的数据
     * @param day : token过期天数
     * @return : token
     */
    public static String getToken(Map<String, String> map, int day) {
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE, day);

        // payload
        JWTCreator.Builder tokenBuilder = JWT.create();
        map.forEach(tokenBuilder::withClaim);

        tokenBuilder.withExpiresAt(instance.getTime());
        return tokenBuilder.sign(Algorithm.HMAC256(SIGN));
    }
    
    /**
     * 获取token信息
     * @param token :
     * @return : token信息
     */
    public static DecodedJWT verify(String token) {
        return JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
    }
}

文章作者: ❤纱雾
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ❤纱雾 !
评论
  目录