简介

Jwt(JSON Web Token)是一种基于RFC 7519标准定义的一种可以安全传输的小巧和自包含的JSON对象。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token计为紧凑且安全,也可直接被用于认证,也可被加密。允许我们在用户和服务器之间传递安全可靠的信息。特别适用于分布式站点的单点登录(SingleSignOn,SSO)。支持移动平台(cookie不支持)。JWT可以使用HMAC算法对secret进行加密或者使用RSA的公钥私钥对其进行签名。

JWT结构

  • Header 头部

    1
    2
    3
    4
    5
    #令牌的类型(即JWT)和使用的签名算法组成
    {
    "alg": "HS256",
    "typ": "JWT"
    }
  • Payload 负载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #由预定义(Registered) 公有(public) 私有(private)三类属性组成
    #Registered,由官方预定,非必需
    {

    iss (issuer):签发人

    sub (subject):主题

    aud (audience):受众

    exp (expiration time):过期时间

    nbf (Not Before):生效时间,在此之前是无效的

    iat (Issued At):签发时间

    jti (JWT ID):编号

    }

    #public: 在使用 JWT 时可以额外定义的载荷
    #private:在信息交互的双方之间约定好的,既不是预定义载荷也不是公有载荷的一类载荷。这一类载荷可能会发生冲突,所以应该谨慎使用。
  • Signature 签名/签证

    主要是把头部的base64UrlEncode与负载的base64UrlEncode拼接起来,再用HMACSHA256进行加盐secret组合加密,最终得到的结果作为签名部分。

JWT示例

1
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiItMSIsInJvbGVJZCI6LTEsInVzZXJJZCI6MSwiaWF0IjoxNjAzMjc1OTE5LCJleHAiOjE2MDMzNjIzMTl9.KVJTpGYMX8IOBFjdNQvmGAsDRQ3J7_2McajtI2WYlss

maven依赖

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>

Jwt工具类代码

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
package com.czm.utils;


import io.jsonwebtoken.*;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Date;


/**
* @Author CZM
* @create 2020/10/20 22:06
*/
public class JwtUtil {
/**
* 过期时间,一天
*/
private static Long EXPIRED_TIME = 24 * 3600 * 1000L;

private static String KEY = "密钥";

/**
* 生产token
* @param userName
* @param userId
* @return
*/
public static String getToken(String userName, Long userId){
String token = Jwts
.builder()
.setSubject(String.valueOf(roleId)) //设置这个JWT的主体,即它的所有人
.claim("userName", userName)
.claim("userId", userId)
.setIssuedAt(new Date()) //jwt的签发时间
.setExpiration(new Date(System.currentTimeMillis()+EXPIRED_TIME))
.signWith(SignatureAlgorithm.HS256, KEY) //设置签名使用的签名算法和签名使用的秘钥
.compact();
return token;
}

/**
* 获取用户名
* @param token
* @return
* @throws Exception
*/
public static String getUserName(String token) {
// Claims claims = Jwts.parser() //得到DefaultJwtParser
// .setSigningKey(KEY) //设置签名的秘钥
// .parseClaimsJws(jwt).getBody();//设置需要解析的jwt
return Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody().get("userName",String.class);
}

/**
* 获取用户id
* @param token
* @return
*/
public static Long getUserId(String token) {
Claims body = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody();
return body.get("userId",Long.class);
}

/**
* 是否过期
* @param token
* @return
*/
public static boolean isExpiration(String token){
Claims claims = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody();
return claims.getExpiration().before(new Date());
}
}

END