##### 什麼是JWT - JWT 是一個開放標準,它定義了一種用於簡潔,自包含的用於通信雙方之間以 JSON 對象的形式安全傳遞信息的方法。 可以使用 HMAC 演算法或者是 RSA 的公鑰密鑰對進行簽名 - **簡單來說: 就是通過一定規範來生成token,然後可以通過解密演算法逆向解密token ...
什麼是JWT
-
JWT 是一個開放標準,它定義了一種用於簡潔,自包含的用於通信雙方之間以 JSON 對象的形式安全傳遞信息的方法。 可以使用 HMAC 演算法或者是 RSA 的公鑰密鑰對進行簽名
-
簡單來說: 就是通過一定規範來生成token,然後可以通過解密演算法逆向解密token,這樣就可以獲取用戶信息
-
優點
- 生產的token可以包含基本信息,比如id、用戶昵稱、頭像等信息,避免再次查庫
- 存儲在客戶端,不占用服務端的記憶體資源
-
缺點
- token是經過base64編碼,所以可以解碼,因此token加密前的對象不應該包含敏感信息,如用戶許可權,密碼等
- 如果沒有服務端存儲,則不能做登錄失效處理,除非服務端改秘鑰
JWT格式組成 頭部、負載、簽名
- header+payload+signature
- 頭部:主要是描述簽名演算法
- 負載:主要描述是加密對象的信息,如用戶的id等,也可以加些規範裡面的東西,如iss簽發者,exp 過期時間,sub 面向的用戶
- 簽名:主要是把前面兩部分進行加密,防止別人拿到token進行base解密後篡改token
關於jwt客戶端存儲
- 可以存儲在cookie,localstorage和sessionStorage裡面
代碼實現
-
依賴引入
<!-- JWT相關 --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency>
-
JWTUtil類,封裝了生產token方法和校驗token方法
@Slf4j public class JWTUtil { /** * 主題 */ private static final String SUBJECT = "xtw"; /** * 加密秘鑰 */ private static final String SECRET = "xtw.com"; /** * 令牌首碼 */ private static final String TOKEN_PREFIX = "xtwcloud-link"; /** * 過期時間 7天 */ private static final long EXPIRED = 1000*60*60*24*7; /** * 生成token * @param loginUser * @return */ public static String geneJsonWebToken(LoginUser loginUser){ if(loginUser == null){ throw new NullPointerException("對象為空"); } String token = Jwts.builder().setSubject(SUBJECT) // 配置payload .claim("head_img",loginUser.getHeadImg()) .claim("account_no",loginUser.getAccountNo()) .claim("username",loginUser.getUserName()) .claim("mail",loginUser.getMail()) .claim("phone",loginUser.getPhone()) .claim("auth",loginUser.getAuth()) .setIssuedAt(new Date()) .setExpiration(new Date(CommonUtil.getCurrentTimestamp()+EXPIRED)) .signWith(SignatureAlgorithm.HS256,SECRET).compact(); token = TOKEN_PREFIX + token; return token; } /** * 校驗token * @param token * @return */ public static Claims checkJWT(String token){ try { final Claims claims = Jwts.parser().setSigningKey(SECRET) .parseClaimsJws(token.replace(TOKEN_PREFIX, "")) .getBody(); return claims; }catch (Exception e){ log.info("jwt 校驗失敗"); return null; } } }
-
案例
-
用戶初次登錄或者token過期,登錄成功返回JWT令牌
public JsonData login(AccountLoginRequest loginRequest) { // 校驗用戶賬號和密碼,等... TODO // 對象變遷 loginRequest -> DO -> DTO(loginUser) // loginRequest:前端輸入 // DO:根據loginRequest從資料庫中提取 // DTO(loginUser):剔除了DO中的敏感欄位,用於生成token // 密碼正確 生成JWT_token String token = JWTUtil.geneJsonWebToken(loginUser); return JsonData.buildSuccess(token); }
-