当前位置:首页 » 《关于电脑》 » 正文

Redis实现JWT(JSON Web TOKEN)自动延长TOKEN过期时间

11 人参与  2024年09月11日 16:01  分类 : 《关于电脑》  评论

点击全文阅读


JWT是JSON WEB TOKEN的简写,常用于生成及校验Token。

常见的使用场景为:用户携带name和秘钥访问后端服务器,应用后端在校验通过后使用JWT生成并返回一串Token,后续用户只需要携带此Token就可以访问服务器,在此不多赘述。

本文目的是基于redis实现token自动更新其过期时间,在校验用户姓名和密码后使用JWT工具类生成会过期的Token,当用户携带此Token访问服务器后会自动延长其过期时间。

例如:用户A携带账户名及秘钥获取token,该token过期时间为2小时,过了1小时后用户再次携带该token访问系统,系统会自动将该token过期时间设置为此刻往后2小时候过期。

1、前提

1.1、JWT工具类
public class JwtUtil {  public static final String JWT_ID = "dshsdhsdgjhjdsh";  /**   * jwt 加密解密密钥(可自行填写Base64加密)   */  private static final String JWT_SECRET = "ahsagsggfTwGGFff";  /**   * 创建JWT   */  public static String createJwt(Map<String, Object> claims, Long time) {    //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;    Date now = new Date(System.currentTimeMillis());    SecretKey secretKey = generalKey();    //下面就是在为payload添加各种标准声明和私有声明了,new一个JwtBuilder,设置jwt的body    JwtBuilder builder = Jwts.builder()            //如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的            .setClaims(claims)            //设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。            .setId(JWT_ID)            //iat: jwt的签发时间            .setIssuedAt(now)            //设置过期时间            .setExpiration(new Date(System.currentTimeMillis() + time))            //设置签名使用的签名算法和签名使用的秘钥            .signWith(signatureAlgorithm, secretKey);    return builder.compact();  }  /**   * 验证jwt   */  public static Claims verifyJwt(String token) {    //签名秘钥,和生成的签名的秘钥一模一样    SecretKey key = generalKey();    Claims claims;    try {      //得到DefaultJwtParser      claims = Jwts.parser()              //设置签名的秘钥              .setSigningKey(key)              .parseClaimsJws(token).getBody();    } catch (Exception e) {      claims = null;    }//设置需要解析的jwt    return claims;  }  /**   * 刷新token并设置过期时间   * @param token 旧的token   * @param newExpirationInMillis 过期时间,单位毫秒   * @return 新的jwt token   */  public static String updateTokenExpiration(String token, Long newExpirationInMillis) {    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;    SecretKey secretKey = generalKey();    Claims claims = Jwts.parser()            .setSigningKey(secretKey)            .parseClaimsJws(token)            .getBody();    claims.setExpiration(new Date(System.currentTimeMillis()+newExpirationInMillis));    return Jwts.builder()            .setClaims(claims)            .setId(JWT_ID)            .signWith(signatureAlgorithm, secretKey)            .compact();  }  /**   * 由字符串生成加密key   *   * @return   */  public static SecretKey generalKey() {    byte[] encodedKey = Base64.decodeBase64(JWT_SECRET);    SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");    return key;  }}
1.2、Maven依赖
<dependency>    <groupId>io.jsonwebtoken</groupId>    <artifactId>jjwt</artifactId>    <version>0.9.1</version></dependency>
1.3、配置过期时间及其他常量
private static final long EXPIRE_TIME = 7200 * 1000;private static final String USER_NAME = "user_name";private static final String SECRET = "password";private static final String JWT_TOKEN_USERNAME = "jwt_token:username";

2、思路与流程

2.1、生成Token

步骤一:用户携带userName和Password访问后端接口,当校验通过后使用JWT工具类生成Token;

 //校验appId和秘钥...//如果校验通过则生成JWT HashMap<String, Object> jwtMap = new HashMap<>(5); jwtMap.put(USER_NAME, userName); jwtMap.put(SECRET, password); //生成JWT String jwt = JwtUtil.createJwt(jwtMap, EXPIRE_TIME);

步骤二:将生成Token及过期时间放入redis数据库中

  String oldToken = (String) redisClient.get(JWT_TOKEN_USERNAME + USER_NAME);  //判断是否存在旧的Token  if (oldToken != null) {      redisClient.delete(oldToken);   }   //多次获取token只生效最后一次   redisClient.set(jwt, jwt, EXPIRE_TIME);   redisClient.set(JWT_TOKEN_USERNAME + appId, jwt, EXPIRE_TIME);
2.2、校验Token
 String valueToken = (String) redisClient.get(token); if (valueToken == null) {      //输出无效信息     log.error("TOKEN:{}无效", token);     //抛异常    throw new Exception();  } else {  Claims claims = JwtUtil.verifyJwt(valueToken);  if (claims == null) {      log.error("TOKEN:{}已过期", token);      throw new Exception();  }   String newToken = JwtUtil.updateTokenExpiration(valueToken, EXPIRE_TIME);   log.info("刷新后的token为:{}", newToken);   redisClient.set(token, newToken, EXPIRE_TIME);   String appKey = (String) claims.get(USER_NAME);   redisClient.expire(JWT_TOKEN_USERNAME + username, EXPIRE_TIME,TimeUnit.MILLISECONDS);   return claims.get(USER_NAME);        }


点击全文阅读


本文链接:http://zhangshiyu.com/post/158333.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 祖母寿宴,侯府冒牌嫡女被打脸了(沈屿安秦秀婉)阅读 -
  • 《雕花锦年,昭都旧梦》(裴辞鹤昭都)完结版小说全文免费阅读_最新热门小说《雕花锦年,昭都旧梦》(裴辞鹤昭都) -
  • 郊区41号(许洛竹王云云)完整版免费阅读_最新全本小说郊区41号(许洛竹王云云) -
  • 负我情深几许(白诗茵陆司宴)完结版小说阅读_最热门小说排行榜负我情深几许白诗茵陆司宴 -
  • 九胞胎孕妇赖上我萱萱蓉蓉免费阅读全文_免费小说在线看九胞胎孕妇赖上我萱萱蓉蓉 -
  • 为保白月光,侯爷拿我抵了债(谢景安花田)小说完结版_完结版小说全文免费阅读为保白月光,侯爷拿我抵了债谢景安花田 -
  • 陆望程映川上官硕《我的阿爹是带攻略系统的替身》最新章节阅读_(我的阿爹是带攻略系统的替身)全章节免费在线阅读陆望程映川上官硕
  • 郑雅琴魏旭明免费阅读_郑雅琴魏旭明小说全文阅读笔趣阁
  • 头条热门小说《乔书意贺宴临(乔书意贺宴临)》乔书意贺宴临(全集完整小说大结局)全文阅读笔趣阁
  • 完结好看小说跨年夜,老婆初恋送儿子故意出车祸_沈月柔林瀚枫完结的小说免费阅读推荐
  • 热推《郑雅琴魏旭明》郑雅琴魏旭明~小说全文阅读~完本【已完结】笔趣阁
  • 《你的遗憾与我无关》宋怀川冯洛洛无弹窗小说免费阅读_免费小说大全《你的遗憾与我无关》宋怀川冯洛洛 -

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1