package com.example.xiaoshiweixinback.business.jwt; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTCreator; import com.auth0.jwt.algorithms.Algorithm; import com.example.xiaoshiweixinback.business.jwt.properties.JwtProperties; import com.example.xiaoshiweixinback.business.utils.ToolUtil; import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwtException; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.UnsupportedEncodingException; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; @Component public class JwtTokenUtil { private static String SECRET = "xiaoshi-weixin-background"; @Autowired private JwtProperties jwtProperties; /** * 获取用户名从token中 */ public String getUsernameFromToken(String token) { return getClaimFromToken(token).getSubject(); } /** * 获取jwt发布时间 */ public Date getIssuedAtDateFromToken(String token) { return getClaimFromToken(token).getIssuedAt(); } /** * 获取jwt失效时间 */ public Date getExpirationDateFromToken(String token) { return getClaimFromToken(token).getExpiration(); } /** * 获取jwt接收者 */ public String getAudienceFromToken(String token) { return getClaimFromToken(token).getAudience(); } /** * 获取私有的jwt claim */ public String getPrivateClaimFromToken(String token, String key) { return getClaimFromToken(token).get(key).toString(); } /** * 获取md5 key从token中 */ public String getMd5KeyFromToken(String token) { return getPrivateClaimFromToken(token, jwtProperties.getMd5Key()); } /** * 获取jwt的payload部分 */ public Claims getClaimFromToken(String token) { return Jwts.parser() .setSigningKey(jwtProperties.getSecret()) .parseClaimsJws(token) .getBody(); } /** * 解析token是否正确,不正确会报异常
*/ public void parseToken(String token) throws JwtException { Jwts.parser().setSigningKey(jwtProperties.getSecret()).parseClaimsJws(token).getBody(); } /** *
     *  验证token是否失效
     *  true:过期   false:没过期
     * 
*/ public Boolean isTokenExpired(String token) { final Date expiration = getExpirationDateFromToken(token); return expiration.before(new Date()); } /** * 生成token(通过用户信息JSON格式和签名时候用的随机数) */ public String generateToken(String userInfo, String randomKey) { Map claims = new HashMap<>(); claims.put(jwtProperties.getMd5Key(), randomKey); return doGenerateToken(claims, userInfo); } public String createToken() throws UnsupportedEncodingException { //签发时间 Date iatDate = new Date(); Calendar nowTime = Calendar.getInstance(); //设置过期时间 -1小时后过期 nowTime.add(Calendar.MINUTE,1); //得到时间 Date expiresDate = nowTime.getTime(); //实例化组成头部header的map Map map = new HashMap(); //声明类型,这里是jwt map.put("typ", "JWT"); //声明加密的算法,通常直接使用HMAC SHA256 map.put("alg", "HS256"); //plyload 载荷,可以理解为承载的物品 // iss: jwt签发者 // sub: jwt所面向的用户 // aud: 接收jwt的一方 // exp: jwt的过期时间,这个过期时间必须要大于签发时间 // nbf: 定义在什么时间之前,该jwt都是不可用的. // iat: jwt的签发时间 // jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。 String token = JWT.create() .withHeader(map)//头部 header .withClaim("iss", "ADMIN") // 载荷 payload .withClaim("aud", "All") .withExpiresAt(expiresDate)//设置过期时间 .withIssuedAt(iatDate)//设置签发时间 .sign(Algorithm.HMAC256(SECRET));//验签singtrue加密 return token; } /** * 生成token */ private String doGenerateToken(Map claims, String subject) { final Date createdDate = new Date(); final Date expirationDate = new Date(createdDate.getTime() + jwtProperties.getExpiration() * 1000); return Jwts.builder() .setClaims(claims) .setSubject(subject) .setIssuedAt(createdDate) .setExpiration(expirationDate) .signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret()) .compact(); } /** * 获取混淆MD5签名用的随机字符串 */ public String getRandomKey() { return ToolUtil.getRandomString(6); } }