一、JWT介紹。
1. 什麼是JWT。
`JWT`全稱`JSON WEB TOKEN`,是一種基於JSON的用於認證的令牌。2. JWT的組成。
頭信息「header」 ,消息體「負載 payload」和簽名「signature」。它們之間用點兒分隔。2.1. 頭信息。
頭信息通常包含兩部分,`type`:代表token的類型,這裏使用jwt。`alt`:使用的Hash算法,如:HMAC-SHA256{
"alg":"HS256",
"typ":"JWT"
}
2.2. 負載。
它包含一些聲明Claim,是一些用戶的狀態和元數據,Claim分三種類型 1)`reserved`。 是官方預定義好的,JWT不會強制你去使用,但是建議你去使用。 常用的有 iss(簽發者),exp(過期時間戳), sub(面向的用戶), aud(接收方), iat(簽發時間) 2)`public` 和 `private`。 這裏都是用戶自己定義的字段。不建議保存私密信息。{
"username":"lisi",
"role":"admin"
}
2.3. 簽名
用頭信息和消息體生成的,生成規則如下:key=“secre_tkey” ; // 自己指定 私有的key
unsignedToken = encodeBase64(header)+ ‘.’ + encodeBase64(payload);
signatrue = HMAC-SHA256(key,unsignedToken);
2.4. 最終
token = encodeBase64(header) + '. ' + encodeBase64(payload) + '. ' + encodeBase64(signature); dfad最終的`token`的樣子:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.
gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI
3. JWT流程圖示
![這裏寫圖片描述](https://img-blog.csdn.net/20180630183827120?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1Bob25lXzEwNzAzMzM1NDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)二、Demo演示
public class JWTUtils {
private static final String SECRET = "huitiankeji";// 公用密鑰--匯天科技
/**
* 生成token
* @param user 對象
* @param maxAge 最大生存時間
* @return 令牌
*/
public static String createToken (User user, long maxAge) throws Exception{
// 設置header
Map<String ,Object> headers =new HashMap<String ,Object>();
headers.put("alg","HS256"); //加密算法
headers.put("typ","JWT");
// 生成token 頭信息 設置過期時間 簽名時間 將用戶信息設置json
String token = JWT.create()
.withHeader(headers)
.withExpiresAt(new Date(System.currentTimeMillis() + maxAge))
.withIssuedAt(new Date())
.withClaim("user", new ObjectMapper().writeValueAsString(user))
.sign(Algorithm.HMAC256(SECRET));
return token;
}
/**
* 解析令牌成爲對象
* @param token 傳入令牌
* @return // 返回對象
* @throws Exception
*/
public static User verifyToken(String token) throws Exception{
// 創建解析器,用來將String的令牌解析成jwt對象
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
// 解析
DecodedJWT jwt = verifier.verify(token);
// 從對象中拿出來user的鍵值對
Claim userClaim = jwt.getClaim("user");
String json = userClaim.asString();
// 用jackson將String轉換成對象
User user = new ObjectMapper().readValue(json, User.class);
return user;
}
}
測試:
public class TestUtils {
public static void main(String[] args) throws Exception {
// 測試獲取
// User user = new User(1, "zhangsan", "123456", "張三!");
// String token = JWTUtils.createToken(user, 30L * 24L * 3600L * 1000L);
// System.out.println(token);
// 測試解析
User user = JWTUtils.verifyToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MzI2ODUyMTYsImlhdCI6MTUzMDA5MzIxNiwidXNlciI6IntcImlkXCI6MSxcInVzZXJuYW1lXCI6XCJ6aGFuZ3NhblwiLFwicGFzc3dvcmRcIjpcIjEyMzQ1NlwiLFwibmFtZVwiOlwi5byg5LiJXCJ9In0._56THpD6T-epjkLcqJBG7hJqaY4vQ7NtU7E5QiuPB8s");
System.out.println(user);
}
}