相逢即是緣,路過點個贊 ^.^php
源碼:https://github.com/yulc-coding/java-note/tree/master/jwt css
JWT是一種用於通訊雙方之間傳遞安全信息的簡潔的、URL安全的表述性聲明規範,常常用在跨域身份驗證。由於存在數字簽名,所以能夠起到防串改的做用前端
相對於傳統的session認證,一般將session保存在服務端,須要服務器去維護。而且在服務器集羣或請求服務跨域的狀況下,須要共享session,使每臺服務器都能讀取session,好比將session持久化,增長了開銷。java
用戶登陸後服務器將相關數據生成一個token返回客戶端
客戶端每次發起請求帶上token
服務器獲取token後校驗token驗證合法性git
{
"alg": "Algorithm 加密方法:HS256",
"cty": "Content Type ",
"typ": "Type" ,
"kid": "Key Id"
}
複製代碼
{
"iss": "Issuer JWT的簽發者",
"aud": "Audience 接收JWT的一方",
"sub": "Subject JWT的主題",
"exp": "Expiration Time JWT的過時時間",
"nbf": "Not Before 在xxx之間,該JWT都是可用的",
"iat": "Issued At 該JWT簽發的時間",
"jti": "JWT ID JWT的惟一身份標識",
"xxx": "自定義屬性"
}
複製代碼
Signature 簽名信息 = 加密算法(header + "." + payload, 密鑰)github
TOKENweb
base64(Header).base64(Payload).Signature
複製代碼
<!-- JWT 支持-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.3</version>
</dependency>
<!-- 很好用的一個工具類包 這裏用來處理json和AES加密-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.0.3</version>
</dependency>
複製代碼
能夠傳入公有聲明的字段,也能夠傳入自定義的字段算法
/**
* 建立token
*
* @param json 須要放入token的參數,多個參數能夠封裝成json或者map
* @return token
*/
public static String createToken(JSONObject json) {
try {
// 加密方式
Algorithm algorithm = Algorithm.HMAC256(SECRET);
return JWT.create()
.withSubject(json.toString())
.withIssuer("ylc")
// 設置過時時間爲1分鐘後
.withExpiresAt(DateUtil.offsetMinute(new Date(), 1))
.withClaim("customString", "自定義參數")
.withArrayClaim("customArray", new Integer[]{1, 2, 3})
.sign(algorithm);
} catch (JWTCreationException exception) {
//Invalid Signing configuration / Couldn't convert Claims.
System.out.println(exception.getMessage());
return null;
}
}
複製代碼
包含:
格式校驗:header.payload.signature
加密方式校驗: Header中的alg值
簽名信息Signature校驗,防止數據被篡改
載體Payload 中公有聲明字段校驗,如iss,jti,exp過時時間的校驗json
/**
* 校驗token 合法性
*
* @param token to verify.
*/
public static boolean verifyToke(String token) {
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm)
// 驗證簽發人是否相同
.withIssuer("ylc")
.build();
/*
* 校驗:
* 格式校驗:header.payload.signature
* 加密方式校驗 Header中的alg
* 簽名信息校驗,防串改
* 載體Payload 中公有聲明字段校驗
*/
verifier.verify(token);
return true;
} catch (JWTVerificationException exception) {
//Invalid signature/claims
System.out.println(exception.getMessage());
return false;
}
}
複製代碼
能夠經過jwt.getClaims() 獲取全部聲明字段
也能夠經過 jwt.getClaim(name) 獲取指定名稱的聲明字段跨域
/**
* 解析token
*
* @param token to decode.
*/
public static void decodeToken(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
Map<String, Claim> claims = jwt.getClaims();
Claim customStringClaim = claims.get("customString");
Claim customArrayClaim = claims.get("customArray");
String issuer = jwt.getIssuer();
String subject = jwt.getSubject();
System.out.println(customStringClaim.asString());
System.out.println(Arrays.toString(customArrayClaim.asArray(Integer.class)));
System.out.println(issuer);
System.out.println(JSONUtil.parseObj(subject));
} catch (JWTDecodeException exception) {
//Invalid token
System.out.println(exception.getMessage());
}
}
複製代碼