目錄
- 目標
- JWT簡介
- JWT的優點
- JWT的資料結構
- JWT登錄鑒權流程
- 代碼
- 官網決議Token
目標
- 熟悉JWT鑒權流程,能通過代碼實作專案上的鑒權(這里以登錄作為案例講解,攔截器實作略,),
JWT簡介
JWT即Json Web Token的縮寫,在Web應用中,將資料以Json格式進行傳輸,通過加密、簽名等演算法保證資料傳輸的安全性,
JWT的優點
- 共享會話:前端保存token,避免了為分布式系統做會話共享的操作;
- 跨語言:Json格式的通用性決定了這一特性;
- 減少資料訪問:用戶資訊保存在token中,避免多次去資料庫查詢用戶資訊,
JWT的資料結構

- 頭部(Base64編碼):使用了哪一種簽名演算法和令牌,
- 有效載荷(Base64編碼):可自定義內容,一般存放用戶的非敏感(如:姓名、角色等)資訊,而敏感資訊(如:密碼、手機號等)是不推薦存放的,
- 驗證簽名:包含:頭部(Base64編碼)、有效載荷(Base64編碼)、密鑰,然后使用我們指定的簽名演算法加密,
JWT登錄鑒權流程

代碼
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
package com.ctx.jwt.auth;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JWTUtils {
//注意:密鑰一定要復雜且保密,
private static final String SIGN = "123456";
public static void main(String[] args) {
//生成token
String jwt = JWTUtils.getJWT();
System.out.println(jwt);
//驗證token
Map<String, Object> map = JWTUtils.checkToken(jwt);
System.out.println(map);
//獲取token資訊
Map<String, Object> tokenInfo = tokenInfo(jwt);
System.out.println(tokenInfo);
}
//生成JWT(實際專案中放在登錄成功后執行,并將其回傳給前端,)
public static String getJWT() {
Map<String, String> map = new HashMap<>();
map.put("loginName", "huangshang");
map.put("studentName", "黃裳");
//過期時間(我這里設定2秒后過期,方便除錯看結果,)
Calendar c = Calendar.getInstance();
c.add(Calendar.SECOND, 2);
//創建一個JWT
JWTCreator.Builder builder = JWT.create();
//有效載荷部分(我這里自定義有效載荷的內容(非敏感資訊)是:登錄名、學生姓名,)
for (Object key : map.keySet()) {
builder.withClaim((String) key, map.get(key));
}
//token過期時間(也可以不設定過期時間,這里根據登錄業務明顯需要,)
builder.withExpiresAt(c.getTime());
//演算法簽名部分(自定義演算法和密鑰,注意:密鑰一定要復雜且保密,)
String token = builder.sign(Algorithm.HMAC256(SIGN));
return token;
}
//驗證token
public static Map<String, Object> checkToken(String token) {
Map<String, Object> map = new HashMap<>();
map.put("result", true);
//創建驗證物件
JWTVerifier v = JWT.require(Algorithm.HMAC256(SIGN)).build();
try {
DecodedJWT decodedJWT = v.verify(token);
} catch (TokenExpiredException e) {
map.put("msg", "token過期");
map.put("result", false);
} catch (SignatureVerificationException e) {
map.put("msg", "無效簽名");
map.put("result", false);
} catch (AlgorithmMismatchException e) {
map.put("msg", "演算法不一致");
map.put("result", false);
} catch (Exception e) {
map.put("msg", "無效的token");
map.put("result", false);
}
return map;
}
//獲取token資訊
public static Map<String, Object> tokenInfo(String token) {
Map<String, Object> map = new HashMap<>();
map.put("result", true);
//創建驗證物件
JWTVerifier v = JWT.require(Algorithm.HMAC256(SIGN)).build();
try {
DecodedJWT decodedJWT = v.verify(token);
String loginName = decodedJWT.getClaim("loginName").asString();
String studentName = decodedJWT.getClaim("studentName").asString();
String date = stampToDate(decodedJWT.getExpiresAt());
map.put("loginName", loginName);
map.put("studentName", studentName);
map.put("date", date);
} catch (TokenExpiredException e) {
map.put("msg", "token過期");
map.put("result", false);
} catch (SignatureVerificationException e) {
map.put("msg", "無效簽名");
map.put("result", false);
} catch (AlgorithmMismatchException e) {
map.put("msg", "演算法不一致");
map.put("result", false);
} catch (Exception e) {
map.put("msg", "無效的token");
map.put("result", false);
}
return map;
}
public static String stampToDate(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = simpleDateFormat.format(date);
return dateString;
}
}
官網決議Token
點擊進入JWT官網;

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/203635.html
標籤:其他
