Fork me on GitHub

JWT操作工具类分享

分享一下个人操作 JWT 的工具类。基于 jjwt 库,这是一个Java圈子最流行的 JWT 操作库。

TIPS

  • 加依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.10.7</version>
    </dependency>
    <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.10.7</version>
    <scope>runtime</scope>
    </dependency>
    <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.10.7</version>
    <scope>runtime</scope>
    </dependency>
  • 工具类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    @Slf4j
    @RequiredArgsConstructor
    @SuppressWarnings("WeakerAccess")
    @Component
    public class JwtOperator {
    /**
    * 秘钥
    * - 默认aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrsssttt
    */
    @Value("${secret:aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrsssttt}")
    private String secret;
    /**
    * 有效期,单位秒
    * - 默认2周
    */
    @Value("${expire-time-in-second:1209600}")
    private Long expirationTimeInSecond;

    /**
    * 从token中获取claim
    *
    * @param token token
    * @return claim
    */
    public Claims getClaimsFromToken(String token) {
    try {
    return Jwts.parser()
    .setSigningKey(this.secret.getBytes())
    .parseClaimsJws(token)
    .getBody();
    } catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException | IllegalArgumentException e) {
    log.error("token解析错误", e);
    throw new IllegalArgumentException("Token invalided.");
    }
    }

    /**
    * 获取token的过期时间
    *
    * @param token token
    * @return 过期时间
    */
    public Date getExpirationDateFromToken(String token) {
    return getClaimsFromToken(token)
    .getExpiration();
    }

    /**
    * 判断token是否过期
    *
    * @param token token
    * @return 已过期返回true,未过期返回false
    */
    private Boolean isTokenExpired(String token) {
    Date expiration = getExpirationDateFromToken(token);
    return expiration.before(new Date());
    }

    /**
    * 计算token的过期时间
    *
    * @return 过期时间
    */
    private Date getExpirationTime() {
    return new Date(System.currentTimeMillis() + this.expirationTimeInSecond * 1000);
    }

    /**
    * 为指定用户生成token
    *
    * @param claims 用户信息
    * @return token
    */
    public String generateToken(Map<String, Object> claims) {
    Date createdTime = new Date();
    Date expirationTime = this.getExpirationTime();


    byte[] keyBytes = secret.getBytes();
    SecretKey key = Keys.hmacShaKeyFor(keyBytes);

    return Jwts.builder()
    .setClaims(claims)
    .setIssuedAt(createdTime)
    .setExpiration(expirationTime)
    // 你也可以改用你喜欢的算法
    // 支持的算法详见:https://github.com/jwtk/jjwt#features
    .signWith(key, SignatureAlgorithm.HS256)
    .compact();
    }

    /**
    * 判断token是否非法
    *
    * @param token token
    * @return 未过期返回true,否则返回false
    */
    public Boolean validateToken(String token) {
    return !isTokenExpired(token);
    }

    public static void main(String[] args) {
    // 1. 初始化
    JwtOperator jwtOperator = new JwtOperator();
    jwtOperator.expirationTimeInSecond = 1209600L;
    jwtOperator.secret = "aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrsssttt";

    // 2.设置用户信息
    HashMap<String, Object> objectObjectHashMap = Maps.newHashMap();
    objectObjectHashMap.put("id", "1");

    // 测试1: 生成token
    String token = jwtOperator.generateToken(objectObjectHashMap);
    // 会生成类似该字符串的内容: eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEiLCJpYXQiOjE1NjU1ODk4MTcsImV4cCI6MTU2Njc5OTQxN30.27_QgdtTg4SUgxidW6ALHFsZPgMtjCQ4ZYTRmZroKCQ
    System.out.println(token);

    // 将我改成上面生成的token!!!
    String someToken = "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEiLCJpYXQiOjE1NjU1ODk4MTcsImV4cCI6MTU2Njc5OTQxN30.27_QgdtTg4SUgxidW6ALHFsZPgMtjCQ4ZYTRmZroKCQ";
    // 测试2: 如果能token合法且未过期,返回true
    Boolean validateToken = jwtOperator.validateToken(someToken);
    System.out.println(validateToken);

    // 测试3: 获取用户信息
    Claims claims = jwtOperator.getClaimsFromToken(someToken);
    System.out.println(claims);

    // 将我改成你生成的token的第一段(以.为边界)
    String encodedHeader = "eyJhbGciOiJIUzI1NiJ9";
    // 测试4: 解密Header
    byte[] header = Base64.decodeBase64(encodedHeader.getBytes());
    System.out.println(new String(header));

    // 将我改成你生成的token的第二段(以.为边界)
    String encodedPayload = "eyJpZCI6IjEiLCJpYXQiOjE1NjU1ODk1NDEsImV4cCI6MTU2Njc5OTE0MX0";
    // 测试5: 解密Payload
    byte[] payload = Base64.decodeBase64(encodedPayload.getBytes());
    System.out.println(new String(payload));

    // 测试6: 这是一个被篡改的token,因此会报异常,说明JWT是安全的
    jwtOperator.validateToken("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEiLCJpYXQiOjE1NjU1ODk3MzIsImV4cCI6MTU2Njc5OTMzMn0.nDv25ex7XuTlmXgNzGX46LqMZItVFyNHQpmL9UQf-aUx");
    }
    }
  • 写配置

    1
    2
    3
    4
    jwt:
    secret: 秘钥
    # 有效期,单位秒,默认2周
    expire-time-in-second: 1209600
  • 使用:

    1
    2
    3
    4
    @Autowired
    private JwtOperator jwtOperator;

    // ...

评论系统未开启,无法评论!