jwt

chaoshang8發表於2024-07-15

一、使用 jjwt

  1. 引入依賴
io.jsonwebtoken jjwt 0.9.1
  1. 生成JWT:demo.JJwtTest.generateJwt()
  2. 解析JWT:demo.JJwtTest.parseJwt()
    二、使用 java-jwt
  3. 引入依賴
com.auth0 java-jwt 3.12.1
  1. 生成JWT:demo.JavaJwtTest.createTokenTest()
  2. 解析JWT:demo.JavaJwtTest.parseTokenTest()

備註

  1. 理解 jwt 的 base64 解碼(驗證地址 https://www.qqxiuzi.cn/bianma/base64.htm)
    1)假設生成的jwt為 A.B.C
    2)A 經過 base64 解碼之後得到:{"typ":"JWT","alg":"HS256"}
    3)B 經過 base64 解碼之後得到:{"sub":"JWT令牌","aud":"member","nbf":1633086966,"iss":"cscloud","body":{"address":"深圳市","name":"zhangsan","age":"26"},"exp":1633088766,"iat":1633086966,"jti":"f8b0eee4ce87448da009e817f76dd114"}
    jwt 官網:https://jwt.io

    io.jsonwebtoken
    jjwt
    0.9.1

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

public class JavaJwtTest {
private static final String JWT_SECRET = "springcloudalibaba";
/**
* 生成JWT
/
@Test
public void createTokenTest() {
Map<String,Object> dataMap = Maps.newHashMap();
dataMap.put("name", "zhangsan");
dataMap.put("age", "26");
dataMap.put("address", "深圳市");
String token = createToken(dataMap);
// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKV1Tku6TniYwiLCJhdWQiOiJtZW1iZXIiLCJuYmYiOjE2MzMwODY5NjYsImlzcyI6ImNzY2xvdWQiLCJib2R5Ijp7ImFkZHJlc3MiOiLmt7HlnLPluIIiLCJuYW1lIjoiemhhbmdzYW4iLCJhZ2UiOiIyNiJ9LCJleHAiOjE2MzMwODg3NjYsImlhdCI6MTYzMzA4Njk2NiwianRpIjoiZjhiMGVlZTRjZTg3NDQ4ZGEwMDllODE3Zjc2ZGQxMTQifQ.vSJ4Ri0LkaummPnRZPzhDpTqJW6rcT9faueMyJdzCzs
System.out.println(token);
}
private String createToken(Map<String,Object> dataMap) {
return JWT.create()
// .withHeader(Maps.newHashMap()) // JWT頭部,有預設值,可以省略
.withClaim("body", dataMap)
.withIssuer("cscloud") // JWT簽發者
.withSubject("JWT令牌") // 主題
.withAudience("member") // 接收JWT的一方
.withExpiresAt(new Date(System.currentTimeMillis() + 1800 * 1000)) // 過期時間
.withNotBefore(new Date(System.currentTimeMillis())) // 指定時間之前 JWT 令牌是不可用的
.withIssuedAt(new Date()) // JWT 簽發時間
.withJWTId(UUID.randomUUID().toString().replace("-","")) // JWT 唯一標識
.sign(Algorithm.HMAC256(JWT_SECRET)); // 實際上是 HS256
}
/
*
* 解析JWT
/
@Test
public void parseTokenTest() {
String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ91.eyJzdWIiOiJKV1Tku6TniYwiLCJhdWQiOiJtZW1iZXIiLCJuYmYiOjE2NDc2ODkyMTQsImlzcyI6ImNzY2xvdWQiLCJib2R5Ijp7ImFkZHJlc3MiOiLmt7HlnLPluIIiLCJuYW1lIjoiemhhbmdzYW4iLCJhZ2UiOiIyNiJ9LCJleHAiOjE2NDc2ODkyNTksImlhdCI6MTY0NzY4OTIxNCwianRpIjoiNTYxYjJiYmMzMzk0NDliZDg5MmU2OTVhOGRlOGZhZjMifQ.CH4lRe0Eijw0nDKBPpMk8IGcehUP-wVqDd7yT2OBjvY";
Map<String, Object> map = parseToken(token);
System.out.println(map);
}
public Map<String, Object> parseToken(String token) {
try {
DecodedJWT jwt = JWT.require(Algorithm.HMAC256(JWT_SECRET)).build().verify(token);
return jwt.getClaim("body").as(Map.class);
} catch (SignatureVerificationException e) {
throw new RuntimeException("token 無效");
} catch (TokenExpiredException e) {
throw new RuntimeException("token 過期");
}
}
}
public class JJwtTest {
private static final String SIGNING_KEY = "123456";
/
*
* 生成JWT
/
@Test
public void generateJwt() {
Map<String,Object> claims = Maps.newHashMap();
claims.put("name", "zhangsan");
claims.put("age", "26");
claims.put("address", "深圳市");
String jwt = generateJwt(claims);
System.out.println(jwt);
}
public String generateJwt(Map<String, Object> claims) {
Date now = new Date();
long expiration = 1800 * 1000;
Date exp = new Date(now.getTime() + expiration);
return Jwts.builder()
.setClaims(claims)
.setSubject("user info") // 主題
.setIssuedAt(now) // 簽發時間
.setExpiration(exp) // 過期時間
.signWith(SignatureAlgorithm.HS256, SIGNING_KEY) // 簽名演算法以及簽名使用的金鑰
.compact();
}
/
*
* 解析 JWT,方式一
* 注意:生成 jwt 時的 setClaims 與 解析 jwt 之後獲得的 Claims 不是等價的
*/
@Test
public void parseJwt() {
String jwt = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIGluZm8iLCJhZGRyZXNzIjoi5rex5Zyz5biCIiwibmFtZSI6InpoYW5nc2FuIiwiZXhwIjoxNjYyODkyMDEwLCJpYXQiOjE2NjI4OTAyMTAsImFnZSI6IjI2In0.HfOzEVQj_D6Lx0pYTgXD5F68RUpYmr_9ETqDX0ZIHas";
Claims claims = Jwts.parser()
.setSigningKey(SIGNING_KEY)
.parseClaimsJws(jwt)
.getBody();
System.out.println("name : " + claims.get("name"));
System.out.println("age : " + claims.get("age"));
System.out.println("address : " + claims.get("address"));
System.out.println(claims.getSubject());
System.out.println(DateUtil.formatDateNormal(claims.getIssuedAt()));
System.out.println(DateUtil.formatDateNormal(claims.getExpiration()));

}
/**
 * 解析 JWT,方式二
 */
@Test
public void parseJwt2() {
    String jwt = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIGluZm8iLCJhZGRyZXNzIjoi5rex5Zyz5biCIiwibmFtZSI6InpoYW5nc2FuIiwiZXhwIjoxNjYyODkyMDEwLCJpYXQiOjE2NjI4OTAyMTAsImFnZSI6IjI2In0.HfOzEVQj_D6Lx0pYTgXD5F68RUpYmr_9ETqDX0ZIHas";
    Map<String, Object> claims = Jwts.parser()
            .setSigningKey(SIGNING_KEY)
            .parseClaimsJws(jwt)
            .getBody();
    System.out.println(claims);
    System.out.println("name : " + claims.get("name"));
    System.out.println("age : " + claims.get("age"));
    System.out.println("address : " + claims.get("address"));
    System.out.println("sub : " + claims.get("sub"));
    System.out.println("iat : " + DateUtil.formatDateNormal(Long.parseLong(claims.get("iat").toString()) * 1000));
    System.out.println("exp : " + DateUtil.formatDateNormal(Long.parseLong(claims.get("exp").toString()) * 1000));
}

}