第一步先引入jar:
<dependency> <groupId>com.nimbusds</groupId> <artifactId>nimbus-jose-jwt</artifactId> <version>8.2.1</version> </dependency>
第二步:工具類封裝:
public final class Jwt { /** * 秘鑰 */ private static final byte[] SECRET = "3d990d2276917dfac04467df11fff26d".getBytes(); /** * 初始化head部分的數據為 * { * "alg":"HS256", * "type":"JWT" * } */ private static final JWSHeader HEADER = new JWSHeader(JWSAlgorithm.HS256, JOSEObjectType.JWT, null, null, null, null, null, null, null, null, null, null, null); /** * 生成token,該方法只在用戶登錄成功后調用 * * @param payload 集合,可以存儲用戶id,token生成時間,token過期時間等自定義字段 * @return token字符串, 若失敗則返回null */ public static String createToken(Map<String, Object> payload) { String tokenString = null; // 創建一個 JWS object JWSObject jwsObject = new JWSObject(HEADER, new Payload(new JSONObject(payload))); try { // 將jwsObject 進行HMAC簽名 jwsObject.sign(new MACSigner(SECRET)); tokenString = jwsObject.serialize(); } catch (JOSEException e) { System.err.println("簽名失敗:" + e.getMessage()); e.printStackTrace(); } return tokenString; } /** * 校驗token是否合法,返回Map集合,集合中主要包含 state狀態碼 data鑒權成功后從token中提取的數據 * 該方法在過濾器中調用,每次請求API時都校驗 * * @param token * @return Map<String, Object> */ public static Map<String, Object> validTokens(String token) { Map<String, Object> resultMap = new HashMap<String, Object>(2); try { JWSObject jwsObject = JWSObject.parse(token); Payload payload = jwsObject.getPayload(); JWSVerifier verifier = new MACVerifier(SECRET); if (jwsObject.verify(verifier)) { JSONObject jsonObj = payload.toJSONObject(); // token校驗成功(此時沒有校驗是否過期) resultMap.put("state", TokenState.VALID.toString()); // 若payload包含ext字段,則校驗是否過期 String exp = "exp"; if (jsonObj.containsKey(exp)) { long expTime = Long.valueOf(jsonObj.get("exp").toString()); long curTime = System.currentTimeMillis(); // 過期了 if (curTime > expTime) { resultMap.clear(); resultMap.put("state", TokenState.EXPIRED.toString()); } } resultMap.put("data", jsonObj); } else { // 校驗失敗 resultMap.put("state", TokenState.INVALID.toString()); } } catch (Exception e) { e.printStackTrace(); // token格式不合法導致的異常 resultMap.clear(); resultMap.put("state", TokenState.INVALID.toString()); } return resultMap; } /** * 生成token的方法 * @param uid 需要保存的數據對象字符串 * @param expTime 有效時間 默認為2小時 * @return */ public static String getToken(String uid,Long expTime){ //獲取生成token Map<String, Object> map = new HashMap<>(3); //建立載荷,這些數據根據業務,自己定義。 map.put("uid", uid); long time= System.currentTimeMillis(); long exptime; if(expTime == null || expTime < 0L ){ exptime= DateUtil.addHour(new Date(time),2).getTime() ; }else{ exptime=time+expTime; } //生成時間 map.put("sta", System.currentTimeMillis()); //過期時間 map.put("exp", exptime); try { String token = Jwt.createToken(map); return token; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 生成token方法, 有效時間 默認為2小時 * @param uid * @return */ public static String getToken(String uid){ return getToken(uid,null); } /** * 驗證token方法 * @param token * @return */ public static Boolean validToken(String token){ //解析token if (ObjectHelper.isNotEmpty(token)) { Map<String, Object> validMap = validTokens(token); String state=(String)validMap.get("state"); if(TokenState.VALID.toString().equals(state)){ return Boolean.TRUE; } } return Boolean.FALSE; } }