JWT簡介
????????JWT定義 JWT全稱為Json web token,也就是 Json 格式的 web token
JWT數據結構
????????1.JWT由三段字符串組成,中間用.分隔
?Project_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiZXhwIjoxNzE2MzcwMTM0LCJpYXQiOjE3MTU3NjUzMzQsImp0aSI6IjllOTljMmUzOWZlMjQzZmE4ZjdhMjkzNmMxYjMwNmQ4In0.qTy7NFaaNkpzNnvAYpu6HZl_4TmjT1mNWuyCPEtUurQ
????????2.JWT 的三個部分依次如下:
Header(頭部)// Header 部分是一個 JSON 對象,描述 JWT 的元數據,通常是下面的樣子。
Payload(負載)// Payload 部分是一個 JSON 對象,用來存放實際需要傳遞的數據
Signature(簽名)// Signature 部分是對前兩部分的簽名,防止數據篡改
? ? ? ? ?3.第一段字符Header,Base64解碼后得到jwt的算法
{
?? ?"typ": "JWT", // TOKEN TYPE ,token類型
?? ?"alg": "HS256" ?//ALGORITHM,算法 哈希256
}
? ? ? ? ?4.第二段字符Payload,解析可得到我們自定義填充的一些數據信息
PAYLOAD是數據載體,可以有自定義數據
{
? "userId": "123456" // 自定義數據
}?
? ? ? ? ?5.第三段字符Signature
Signature 部分是對前兩部分的簽名,防止數據篡改。
?具體實現方法:
- ? 導入jar
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.8.1</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.16</version></dependency>
- 封裝工具類
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;public class JwtTokenUtil {//過期時間public static final Long EXPIRATION = 604800l;// 密鑰 設置的越復雜越好public static final String SECRET = "ec15df77f55d819a3876f6543f7d89";//token前綴public static final String PREFIX = "Project_";public JwtTokenUtil() {}public static void main(String[] args) {System.out.println(generateToken("1"));}public static String generateToken(String userId) {return PREFIX + JWT.create().withSubject(userId).withIssuedAt(new Date()).withJWTId(UUID.fastUUID().toString(true)).withExpiresAt(generateExpirationDate()).sign(Algorithm.HMAC256(SECRET));}public static Date generateExpirationDate() {return new Date(System.currentTimeMillis() + (long)(EXPIRATION * 1000));}public boolean isTokenExpired(Date expiresAt) {return expiresAt.before(DateUtil.date());}public DecodedJWT decode(String token) {try {return JWT.decode(this.subStrToken(token));} catch (JWTDecodeException var3) {throw new BadCredentialsException("token 解析出錯", var3);}}public String getUserIdFromSubject(String subject) {try {if (StrUtil.isEmpty(subject)) {throw new UsernameNotFoundException("從token中無法解析出用戶ID");} else {String[] subjects = subject.split("#,#");String userName;if (ArrayUtil.isNotEmpty(subjects)) {userName = subjects[0];} else {userName = subject;}return userName;}} catch (Exception var4) {throw new BadCredentialsException("從token中解析用戶ID出錯", var4);}}public void verify(String token, String userId) {Algorithm algorithm = Algorithm.HMAC256(SECRET);JWTVerifier verifier = JWT.require(algorithm).withSubject(userId).build();verifier.verify(this.subStrToken(token));}private String subStrToken(String token) {if (token.startsWith(PREFIX)) {token = token.substring(PREFIX.length());}return token;}
}
- 測試