| | |
| | | package com.dy.pmsWechat.util; |
| | | |
| | | import cn.hutool.jwt.Claims; |
| | | import com.alibaba.druid.util.StringUtils; |
| | | import io.jsonwebtoken.*; |
| | | import io.jsonwebtoken.security.Keys; |
| | | |
| | | import javax.crypto.SecretKey; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.Date; |
| | | import java.util.Map; |
| | | |
| | | |
| | | public class JwtUtil { |
| | | //token字符串有效时间 |
| | | private static long tokenExpiration = 24*60*60*1000; |
| | | //加密编码秘钥 |
| | | private static String tokenSignKey = "123456"; |
| | | |
| | | //根据userid 和 username 生成token字符串 |
| | | public static String createToken(Long userId, String userName) { |
| | | String token = Jwts.builder() |
| | | //设置token分类 |
| | | .setSubject("GGKT-USER") |
| | | //token字符串有效时长 |
| | | .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)) |
| | | //私有部分(用户信息) |
| | | .claim("userId", userId) |
| | | .claim("userName", userName) |
| | | //根据秘钥使用加密编码方式进行加密,对字符串压缩 |
| | | .signWith(SignatureAlgorithm.HS512, tokenSignKey) |
| | | .compressWith(CompressionCodecs.GZIP) |
| | | .compact(); |
| | | return token; |
| | | /** |
| | | * 生成jwt |
| | | * 使用Hs256算法, 私匙使用固定秘钥 |
| | | * |
| | | * @param secretKey jwt秘钥 |
| | | * @param ttlMillis jwt过期时间(毫秒) |
| | | * @param claims 设置的信息 |
| | | * @return |
| | | */ |
| | | public static String createJwt(String secretKey, long ttlMillis, Map<String, Object> claims) { |
| | | // 指定签名的时候使用的签名算法,也就是header那部分 |
| | | // SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; |
| | | |
| | | // 生成JWT的时间 |
| | | long expMillis = System.currentTimeMillis() + ttlMillis; |
| | | Date exp = new Date(expMillis); |
| | | |
| | | //生成 HMAC 密钥,根据提供的字节数组长度选择适当的 HMAC 算法,并返回相应的 SecretKey 对象。 |
| | | SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); |
| | | |
| | | // 设置jwt的body |
| | | JwtBuilder builder = Jwts.builder() |
| | | // 设置签名使用的签名算法和签名使用的秘钥 |
| | | .signWith(key) |
| | | // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的 |
| | | .claims(claims) |
| | | // 设置过期时间 |
| | | .expiration(exp); |
| | | return builder.compact(); |
| | | } |
| | | |
| | | //从token字符串获取userid |
| | | public static Long getUserId(String token) { |
| | | if(StringUtils.isEmpty(token)) return null; |
| | | Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token); |
| | | Claims claims = claimsJws.getBody(); |
| | | Integer userId = (Integer)claims.get("userId"); |
| | | return userId.longValue(); |
| | | } |
| | | /** |
| | | * Token解密 |
| | | * |
| | | * @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个 |
| | | * @param token 加密后的token |
| | | * @return |
| | | */ |
| | | public static Claims parseJWT(String secretKey, String token) { |
| | | |
| | | //从token字符串获取getUserName |
| | | public static String getUserName(String token) { |
| | | if(StringUtils.isEmpty(token)) return ""; |
| | | Jws<Claims> claimsJws |
| | | = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token); |
| | | Claims claims = claimsJws.getBody(); |
| | | return (String)claims.get("userName"); |
| | | //生成 HMAC 密钥,根据提供的字节数组长度选择适当的 HMAC 算法,并返回相应的 SecretKey 对象。 |
| | | SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); |
| | | |
| | | // 得到DefaultJwtParser |
| | | JwtParser jwtParser = Jwts.parser() |
| | | // 设置签名的秘钥 |
| | | .verifyWith(key) |
| | | .build(); |
| | | Jws<Claims> jws = jwtParser.parseSignedClaims(token); |
| | | Claims claims = jws.getPayload(); |
| | | return claims; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |