软件编程
位置:首页>> 软件编程>> java编程>> Spring Boot实现JWT token自动续期的实现

Spring Boot实现JWT token自动续期的实现

作者:dreaming9420  发布时间:2022-02-12 03:48:40 

标签:Spring,Boot,JWT,token,自动续期

1.为什么要 token自动续期

token中一般会包含用户的基本信息,为了保证token的安全性,一般会将token的过期时间设置的比较短,但是这样会导致用户因为token过期需要频繁登录,因此需要token自动续期。

2.如何实现token自动续期

登录时将token存入redis中,缓存有效期设置为 token有效时间的两倍(比token有效时间长即可)。


//创建token
String token = JwtUtil.createToken(sysUser.getId(), user.getUserName());
//将token放入redis中,key为用户的手机号+"token"
redisUtil.set(sysUser.getPhone() + GlobalConstant.TOKEN, token, JwtUtil.EXPIRE_TIME*2);

Spring Boot实现JWT token自动续期的实现

在 * 中重写public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)方法


/**
    * token自动续期
    *
    * @param sysUser 用户实体
    * @return 是否刷新成功
    */
   private boolean refreshToken(SysUser sysUser) {
       String token = request.getHeader(GlobalConstant.TOKEN);
       String cacheToken = (String) (redisUtil.get(sysUser.getPhone() + GlobalConstant.TOKEN));
       //请求头中不存在token,返回false
       if (StringUtil.isEmpty(token)) {
           logger.error("token不存在");
           return false;
       }
       //用户是否登录只根据redis中token是否存在决定,redis中不存在token,返回false
       if (StringUtil.isEmpty(cacheToken)) {
           logger.error("用户未登录");
           return false;
       }
       try {
           //验证请求头中的token是否合法
           JwtUtil.verify(token);
       } catch (TokenExpiredException tokenExpiredException) {
           /*若抛出token过期异常,检查redis中的是否存在token
           如果存在,说明用户仍在操作,只是请求头中的token已经过期,此时需要对token进行续期*/
           if (redisUtil.hasKey(sysUser.getPhone() + GlobalConstant.TOKEN)) {
               //生成新的token,并以之前的key作为key放入redis中,以此重新刷新redis中的token的过期时间
               String newToken = JwtUtil.createToken(sysUser.getId(), sysUser.getUserName());
               redisUtil.set(sysUser.getPhone() + GlobalConstant.TOKEN, newToken, JwtUtil.EXPIRE_TIME * 2);
               return true;
           }
       } catch (Exception e) {
           //若抛出除token过期异常之外的其他异常,说明该token不合法
           logger.error("token不合法");
           return false;
       }
       return true;
   }

Spring Boot实现JWT token自动续期的实现

Spring Boot实现JWT token自动续期的实现

JwtUtil工具类如下


import com.admin.common.constant.GlobalConstant;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;

import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;

public class JwtUtil {
   /**
    * token私钥,不可以暴露
    */
   public static final String TOKEN_SECRET_KEY = "tokenSecretKey";
   /**
    * token过期时间(秒)
    */
   public static final int EXPIRE_TIME = 60;

/**
    * 创建token
    *
    * @param userId   用户ID
    * @param userName 用户名
    * @return token
    */
   public static String createToken(Long userId, String userName) {
       Calendar calendar = Calendar.getInstance();
       calendar.add(Calendar.SECOND, EXPIRE_TIME);
       return JWT.create()
               //签发对象
               .withAudience(userId + "")
               //载荷
               .withClaim("userName", userName)
               //签发时间
               .withIssuedAt(new Date())
               //有效时间
               .withExpiresAt(calendar.getTime())
               //加密
               .sign(Algorithm.HMAC256(TOKEN_SECRET_KEY));
   }

/**
    * 验证token合法性
    *
    * @param token token
    * @return token是否合法
    */
   public static void verify(String token) {
       JWT.require(Algorithm.HMAC256(TOKEN_SECRET_KEY)).build().verify(token);
   }

/**
    * 通过token获取userId
    *
    * @return userId
    */
   public static Long getUserIdByToken(HttpServletRequest request) {
       String token = request.getHeader(GlobalConstant.TOKEN);
       String userId = JWT.decode(token).getAudience().get(0);
       return Long.valueOf(userId);
   }
}

来源:https://blog.csdn.net/dreaming9420/article/details/121750732

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com