- 依赖:jjwt和jackson-databind的版本都至少需要2.10.5及以上
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
</dependency>
-
jjwt的作用:是生成、解析和校验Json Web Token(JWT)。JWT是一种用于身份验证的令牌,由三部分组成:头部、载荷和签名。使用JWT可以保护API端点,允许用户进行无状态身份验证。
-
JJwtUtil.java
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JJwtUtil {
private static final String USER_CLAIMS_KEY = "user";
// 过期时间
@Value("${jwt.expire-time}")
private long EXPIRE_TIME;
// 密钥
@Value("${jwt.secret}")
private String SECRET;
/**
* 创建JWT Token
* @param payload 载荷(Claims)
* @return JWT Token
*/
public String createToken(Map<String, Object> payload) {
// 1. 创建一个密钥
SecretKey key = Keys.hmacShaKeyFor(SECRET.getBytes(StandardCharsets.UTF_8));
// 2. 创建JWT Builder
// 注意:这里的签名算法不能是 RS256,需要使用 HS256
io.jsonwebtoken.JwtBuilder builder = Jwts.builder()
.setClaims(payload)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRE_TIME))
.signWith(key, SignatureAlgorithm.HS256);
// 3. 生成JWT Token
return builder.compact();
}
/**
* 解析JWT Token
* @param token JWT Token
* @return 载荷(Claims)
*/
public Map<String, Object> parseToken(String token) {
// 1. 获取密钥
SecretKey key = Keys.hmacShaKeyFor(SECRET.getBytes(StandardCharsets.UTF_8));
// 2. 解析JWT Token
Claims claims = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();
// 3. 将Claims里的内容转换成Map
Map<String, Object> payload = new HashMap<>(claims);
payload.remove("exp");
payload.remove("iat");
payload.remove("iss");
payload.remove("aud");
payload.remove("nbf");
payload.remove("sub");
payload.remove("jti");
return payload;
}
/**
* 获取JWT Token的过期时间
* @param token JWT Token
* @return 过期时间
*/
public Date getExpirationDateFromToken(String token) {
Claims claims = parseClaims(token);
if (claims != null) {
return claims.getExpiration();
}
return null;
}
/**
* 验证JWT Token是否有效
* @param token JWT Token
* @return 是否有效
*/
public boolean validateToken(String token) {
try {
parseClaims(token);
return true;
} catch (Exception e) {
return false;
}
}
/**
* 获取payload中的用户信息
* @param token JWT Token
* @return 用户信息
*/
public Map<String, Object> getUserFromToken(String token) {
Map<String, Object> user = null;
Claims claims = parseClaims(token);
if (claims != null) {
user = (Map<String, Object>) claims.get(USER_CLAIMS_KEY);
}
return user;
}
/**
* 解析JWT Token中的Claims
* @param token JWT Token
* @return Claims
*/
private Claims parseClaims(String token) {
try {
SecretKey key = Keys.hmacShaKeyFor(SECRET.getBytes(StandardCharsets.UTF_8));
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
return null;
}
}
}
- 方法说明:
- createToken:创建JWT Token。参数payload为Map类型的载荷内容,在方法中自动生成并设置过期时间,返回生成的JWT Token字符串。
- parseToken:解析JWT Token字符串,返回Map类型的载荷内容。
- getExpirationDateFromToken:获取JWT Token的过期时间,返回Date类型。
- validateToken:验证JWT Token是否有效,返回boolean类型。
- getUserFromToken:获取JWT Token中用户信息。方法中定义的常量USER_CLAIMS_KEY表示用户信息在载荷中的键名,解析JWT Token后从Claims中取出并返回。
- parseClaims:解析并返回JWT Token的Claims。该方法是createToken、validateToken、getUserFromToken等方法的基础方法。