一、添加依賴包
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
<version>0.11.1</version>
<scope>compile</scope> <!-- Not runtime -->
</dependency>
二、示例代碼
@RestController
@RequestMapping("/token")
public class TokenController {
/**
* SECRET 是簽名密鑰,只生成一次即可,生成方法:
* Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
* String secretString = Encoders.BASE64.encode(key.getEncoded()); # 本文使用 BASE64 編碼
* */
private static final String SECRET = "cuAihCz53DZRjZwbsGcZJ2Ai6At+T142uphtJMsk7iQ=";
private static final String USER_INFO_KEY = "user_info";
private static final long TOKEN_EXPIRED_SECOND = 60;
@Autowired
private HttpServletRequest request;
@RequestMapping("/get")
public Object get() {
Map<String, Object> claims = new HashMap<>();
UserInfo userInfo = new UserInfo();
userInfo.setId("123456");
userInfo.setName("測試abc123");
claims.put(USER_INFO_KEY, userInfo);
// 添加自定義參數
JwtBuilder jwtBuilder = Jwts.builder()
.setClaims(claims);
long currentTimeMillis = System.currentTimeMillis();
// 設置過期時間
jwtBuilder.setExpiration(new Date(currentTimeMillis + TOKEN_EXPIRED_SECOND * 1000));
SecretKey secretKey = getSecretKey();
jwtBuilder.signWith(secretKey);
String jwsStr = jwtBuilder.compact();
return jwsStr;
}
@RequestMapping("/verify")
public Object verify() {
String token = request.getHeader("Authorization");
SecretKey secretKey = getSecretKey();
Jws<Claims> jws = Jwts.parserBuilder()
// 解析 JWT 的服務器與創建 JWT 的服務器的時鍾不一定完全同步,此設置允許兩台服務器最多有 3 分鍾的時差
.setAllowedClockSkewSeconds(180L)
.setSigningKey(secretKey)
// 默認情況下 JJWT 只能解析 String, Date, Long, Integer, Short and Byte 類型,如果需要解析其他類型則需要配置 JacksonDeserializer
.deserializeJsonWith(new JacksonDeserializer(Maps.of(USER_INFO_KEY, UserInfo.class).build()))
.build().parseClaimsJws(token);
Claims claims = jws.getBody();
UserInfo userInfo = claims.get(USER_INFO_KEY, UserInfo.class);
return userInfo;
}
/**
* SecretKey 根據 SECRET 的編碼方式解碼后得到:
* Base64 編碼:SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretString));
* Base64URL 編碼:SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64URL.decode(secretString));
* 未編碼:SecretKey key = Keys.hmacShaKeyFor(secretString.getBytes(StandardCharsets.UTF_8));
* */
private SecretKey getSecretKey() {
byte[] encodeKey = Decoders.BASE64.decode(SECRET);
return Keys.hmacShaKeyFor(encodeKey);
}
}
注意 setAllowedClockSkewSeconds 和 deserializeJsonWith 部分的配置