头部(header,一般使用base64加密)
JWT的头部有两部分信息:
声明类型,这里是JWT
声明加密的算法,通常直接使用HMAC SHA256
载荷(payload)
该部分一般存放一些有效的信息(如用户名)。
iss:JWT的签发者
sub: JWT所面向的用户
aud: 接收该JWT的一方
exp(expires): 什么时候过期,时间戳
iat(issued at): 在什么时候签发的
签名(signature)
前面两部分都是使用Base64进行编码的,即前端可以解开知道里面的信息。signature 需要使用编码后的header和payload以及我们提供的一个密钥(盐值),然后使用header中指定的签名算法进行签名。签名的作用是保证 JWT 没有被篡改过。
package com.yeb_server.config.security;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
//JWT Token工具类
@Component
public class JwtTokenUtil {
//用户名key
private static final String CLAIM_KEY_USERNAME = "sub";
//生成时间key
private static final String CLAIM_KEY_CREATED = "created";
//密钥
private String secret = "1234";
//失效时间
private Long expiration = 60*60;
//根据用户信息生成token
public String generateToken(UserDetails userDetails){
Map<String,Object> claims = new HashMap<>();
claims.put(CLAIM_KEY_USERNAME,userDetails.getUsername());
claims.put(CLAIM_KEY_CREATED,new Date());
return generateToken(claims);
}
//根据荷载生成JWT Token
private String generateToken(Map<String,Object> claims){
return Jwts.builder()
.setClaims(claims)
//过期时间
.setExpiration(generateExpirationDate())
//secret:盐值
.signWith(SignatureAlgorithm.HS512,secret)
.compact();
}
//生成token失效时间
private Date generateExpirationDate() {
return new Date(System.currentTimeMillis() + expiration*1000);
}
//从token中获取用户名
public String getUsernameFromToken(String token){
String username;
try{
Claims claims = getClaimsFormToken(token);
username = claims.getSubject();
}catch (Exception e){
username = null;
}
return username;
}
//从jwt中获荷载
private Claims getClaimsFormToken(String token) {
Claims claims = null;
try {
claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}catch (Exception e){
e.printStackTrace();
}
return claims;
}
//判断token是否有效
public boolean validateToken(String token,UserDetails userDetails){
String username = getUsernameFromToken(token);
return username.equals(userDetails.getUsername()) && ! isTokenExpired(token);
}
//判断token是否失效
private boolean isTokenExpired(String token) {
Date expireDate = getExpiredDtaeFromToken(token);
return expireDate.before(new Date());
}
//从token中获取过期时间
private Date getExpiredDtaeFromToken(String token) {
Claims claims = getClaimsFormToken(token);
return claims.getExpiration();
}
//判断token是否可以被刷新,过期可被刷新
public boolean canRefresh(String token){
return !isTokenExpired(token);
}
//刷新token
public String refershToken(String token){
Claims claims = getClaimsFormToken(token);
claims.put(CLAIM_KEY_CREATED,new Date());
return generateToken(claims);
}
}