JwtHelper

JwtHelper

token⼝令⽣成

一、生成token字符串

 public static String createToken(Long userId, Integer userType) {
     // 创建一个JWT生成器,并配置相关信息
        String token = Jwts.builder()
                .setSubject("YYGH-USER")// 设置JWT主题(通常是令牌的用途描述)
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))//设置JWT的过期时间
                .claim("userId", userId)//添加一个名为 "userId" 的声明,用于存储用户ID
// .claim("userName", userName)
                .claim("userType", userType)// 添加一个名为 "userType" 的声明,用于存储用户类型
                .signWith(SignatureAlgorithm.HS512, tokenSignKey)// 使用HS512算法进行签名,并提供签名密钥
                .compressWith(CompressionCodecs.GZIP) // 使用GZIP进行压缩(可选)
                .compact(); // 构建JWT令牌并返回
        return token;
    }

逐行解释:

  1. String token = Jwts.builder():创建一个JWT生成器。
  2. .setSubject("YYGH-USER"):设置JWT的主题(subject),通常用于描述令牌的用途。在这里,主题被设置为 “YYGH-USER”,可能表示这是用于医院挂号系统(YYGH)的用户令牌。
  3. .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)):设置JWT的过期时间。tokenExpiration 可能是一个表示令牌有效期的时间间隔。在当前时间基础上加上有效期,以确定令牌何时过期。
  4. .claim("userId", userId):添加一个声明(claim)到JWT中。在这里,我们添加了一个名为 “userId” 的声明,用于存储用户的ID。声明是JWT中的一些附加数据。
  5. .claim("userType", userType):添加另一个声明,名为 “userType”,用于存储用户的类型信息。
  6. .signWith(SignatureAlgorithm.HS512, tokenSignKey):使用HS512算法对JWT进行签名,并提供签名密钥 tokenSignKey。签名是为了确保令牌的完整性和安全性,以防止被篡改。
  7. .compressWith(CompressionCodecs.GZIP):可选步骤,使用GZIP进行压缩。这可以减小令牌的大小,但不是必需的。
  8. .compact():构建JWT令牌并返回。

最终,这个方法会返回一个包含用户信息的JWT令牌,可以用于身份验证和授权,或者传递给其他系统以证明用户的身份和权限。

二、从token字符串获取userid

它用于从给定的JWT令牌字符串中提取用户ID:

//从token字符串获取userid
public static Long getUserId(String token) {
     // 如果token为空或null,直接返回null
    if (StringUtils.isEmpty(token)) 
        return null;
     // 解析JWT令牌
    Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
    // 获取JWT中的声明(claims)
    Claims claims = claimsJws.getBody();
     // 从声明中获取用户ID(作为Integer类型)
    Integer userId = (Integer) claims.get("userId");
      // 返回用户ID的Long类型
    return userId.longValue();
}

逐行解释:

  1. if (StringUtils.isEmpty(token)) return null;:首先检查输入的token是否为空或null,如果是的话,直接返回null,避免后续操作出错。
  2. Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);:解析JWT令牌。这里使用了JWT的解析器,设置了签名密钥 tokenSignKey 来验证令牌的完整性,并使用 parseClaimsJws 方法解析JWT字符串 token
  3. Claims claims = claimsJws.getBody();:获取JWT中的声明(claims),这包括了在创建令牌时添加的所有声明(例如,userId、userType等)。
  4. Integer userId = (Integer) claims.get("userId");:从JWT声明中获取名为 “userId” 的声明的值。注意,这里获取到的是一个 Integer 类型的用户ID。
  5. return userId.longValue();:将 Integer 类型的用户ID转换为 Long 类型,并返回。

最终,这个方法返回从JWT令牌中提取的用户ID。这是一种常见的用法,用于从令牌中提取有关用户身份和权限的信息。如果令牌无效或不包含所需的信息,该方法会返回null或抛出异常,具体行为取决于JWT解析库的实现。

三、/从token字符串获取userType

//从token字符串获取userType
public static Integer getUserType(String token) {
    if (StringUtils.isEmpty(token))
        return null;
      Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
    Claims claims = claimsJws.getBody();
    return (Integer) (claims.get("userType"));
}

四、/从token字符串获取userName

//从token字符串获取userName
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");
}

五、判断token是否有效

public static boolean isExpiration(String token) {
    try {
        boolean isExpire = Jwts.parser()
                .setSigningKey(tokenSignKey)
                .parseClaimsJws(token)
                .getBody()
                .getExpiration().before(new Date());
        //没有过期,有效,返回false
        return isExpire;
    } catch (Exception e) {
        //过期出现异常,返回true
        return true;
    }
}

解释:

getExpiration().before(new Date()) 是一个日期比较表达式,用于检查某个日期是否在当前日期之前。以下是解释:

  • getExpiration():这是一个方法,通常用于从某个对象中获取日期(通常是一个日期时间对象)的过期时间。在上下文中,它可能用于获取JWT令牌的过期时间。

  • new Date():这是一个Java中用于创建表示当前日期和时间的对象的方法。new Date() 创建了一个包含当前日期和时间的Date对象。

  • before(new Date()):这是一个日期比较方法,通常用于检查一个日期是否在另一个日期之前。在这里,它用于检查 getExpiration() 方法返回的日期是否在当前日期之前。

如果 getExpiration() 返回的日期早于(即在之前)当前日期,表达式将返回 true,表示令牌已经过期。这是在JWT令牌的上下文中非常有用的,因为它允许您检查令牌是否有效或已过期。如果返回 true,则通常需要重新进行身份验证或者拒绝使用过期的令牌。

六、刷新Token

/**
 * 刷新Token
 *
 * @param token
 * @return
 */
public String refreshToken(String token) {
    String refreshedToken;
    try {
    // 解析原始令牌,获取令牌中的声明
        final Claims claims = Jwts.parser()
                .setSigningKey(tokenSignKey)
                .parseClaimsJws(token)
                .getBody();
            //使用原始令牌中的信息创建一个新的令牌    
        refreshedToken = JwtHelper.createToken(getUserId(token), getUserType(token));
    } catch (Exception e) {
        // 发生异常时,将刷新令牌设置为null
        refreshedToken = null;
    }
    return refreshedToken;
}
  1. String refreshedToken;:声明一个字符串变量 refreshedToken,用于存储刷新后的令牌。
  2. try { ... } catch (Exception e) { ... }:使用异常处理块来捕获可能发生的异常,例如JWT解析失败或其他问题。
  3. final Claims claims = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody();:在 try 块中,首先解析原始的JWT令牌 token。这里使用了JWT解析器,提供了签名密钥 tokenSignKey,并通过 parseClaimsJws 方法解析JWT字符串。然后,使用 getBody() 方法获取JWT中的声明(claims),这些声明包含在原始令牌中。
  4. refreshedToken = JwtHelper.createToken(getUserId(token), getUserType(token));:使用原始令牌中的信息创建一个新的令牌。getUserId(token)getUserType(token) 分别用于从原始令牌中获取用户ID和用户类型,然后使用这些信息来创建新的令牌。这个新令牌被赋值给 refreshedToken
  5. refreshedToken = null;:如果在解析或创建令牌过程中发生异常(在 catch 块中),则将 refreshedToken 设置为 null,表示刷新失败或发生错误。
  6. return refreshedToken;:最后,返回刷新后的令牌。如果刷新成功,它将包含新的信息;如果刷新失败,它将为 null

七、整体代码

/**
 * @ClAssName JwtHelper
 * @Description token⼝令⽣成
 * @Author 欧妮甲是神仙
 * @Date 2023/9/30 21:{MINUTE}
 */
public class JwtHelper {
    private static long tokenExpiration = 24 * 60 * 60 * 1000;
    private static String tokenSignKey = "123456";

    //⽣成token字符串
    public static String createToken(Long userId, Integer userType) {
        String token = Jwts.builder()
                .setSubject("YYGH-USER")
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
                .claim("userId", userId)
// .claim("userName", userName)
                .claim("userType", userType)
                .signWith(SignatureAlgorithm.HS512, tokenSignKey)
                .compressWith(CompressionCodecs.GZIP)
                .compact();
        return token;
    }

    //从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字符串获取userType
    public static Integer getUserType(String token) {
        if (StringUtils.isEmpty(token)) return null;
        Jws<Claims> claimsJws
                = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws
                (token);
        Claims claims = claimsJws.getBody();
        return (Integer) (claims.get("userType"));
    }

    //从token字符串获取userName
    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");
    }

    //判断token是否有效
    public static boolean isExpiration(String token) {
        try {
            boolean isExpire = Jwts.parser()
                    .setSigningKey(tokenSignKey)
                    .parseClaimsJws(token)
                    .getBody()
                    .getExpiration().before(new Date());
            //没有过期,有效,返回false
            return isExpire;
        } catch (Exception e) {
            //过期出现异常,返回true
            return true;
        }
    }

    /**
     * 刷新Token
     *
     * @param token
     * @return
     */
    public String refreshToken(String token) {
        String refreshedToken;
        try {
            final Claims claims = Jwts.parser()
                    .setSigningKey(tokenSignKey)
                    .parseClaimsJws(token)
                    .getBody();
            refreshedToken = JwtHelper.createToken(getUserId(token), getUserType(token));
        } catch (Exception e) {
            refreshedToken = null;
        }
        return refreshedToken;
    }

}

八、应用

/**
 * @ClAssName AuthContextHolder
 * @Description 从request请求中获取token⼝令
 * @Author 欧妮甲是神仙
 * @Date 2023/9/30 22:{MINUTE}
 */
public class AuthContextHolder {
    //从请求头token·获取userid
    public static Long getUserIdToken(HttpServletRequest request) {
        //从请求头token
        String token = request.getHeader("token");
        //调⽤⼯具类
        Long userId = JwtHelper.getUserId(token);
        return userId;
    }
    //从请求头token获取name
    public static String getUserName(HttpServletRequest request) {
        //从header获取token
        String token = request.getHeader("token");
        //jwt从token获取username
        String userName = JwtHelper.getUserName(token);
        return userName;
    }

}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值