redis缓存token设置jwt令牌过期时间

登录接口

在上文中 我们已经设置了自定义登录接口自定义拦截器jwt登录校验接口模拟账号登录_jwt自定义拦截器-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/2202_75352238/article/details/138424691?spm=1001.2014.3001.5501

但是上文jwt过期时间是由yml文件中配置的,比较不优雅,我们今天来用redis缓存token 的方法来进行 jwt的过期设置。

修改部分

我们把jwt过期时间来注释掉,实体类中的也注释掉

然后把创建jwt令牌的 创建方法参数也修改一下

 如果这样设置不加修改的话,等于说我们登陆一次令牌就永不过期,下面 我们来思考 怎么把令牌加入redis 来进行缓存

思路分析

我们可以看我们的logincontroller方法,我们的方法中 是  如果是请求的登录接口 ,我们就对登录的用户名密码与数据库对应,如果登录用户密码正确,那么就生成一个token,然后后续的其他接口来进行访问的时候都会携带这个token ,如果用户名密码 不与数据库中的一致,那么就抛出异常

在此之中的逻辑,我们在什么时机加入redis缓存并且设置过期时间呢?

我们可以这样想,我们登录用户名密码正确的时候生成了token并且返回前端,之后请求都会携带token,那我们 可以在 生成token的时候,把token 加入redis缓存中并且设置一个过期时间,然后在拦截器 的实现那里,每次非登录请求的时候我们都访问redis 中的token数据,如果token数据过期,那么就抛异常,如果不过期就继续访问接口放行

具体实现

controller代码

@RestController
@Slf4j
@RequiredArgsConstructor
public class LoginController {
    private  final UserLoginService userLoginService;
    private final JwtProperties jwtProperties;
    private  final RedisTemplate redisTemplate;
    @PostMapping("/userLogin")
    public Result userLogin( String username,  String password) {
          password=DigestUtils.md5DigestAsHex(password.getBytes());
        LambdaQueryWrapper<UserLogin> userLoginLambdaQueryWrapper = new LambdaQueryWrapper<UserLogin>()
                .eq(UserLogin::getUsername, username);
        UserLogin userLogin = userLoginService.getOne(userLoginLambdaQueryWrapper);
        if(userLogin==null && userLogin.getUsername().isEmpty()){
            return Result.error("查询不到用户");
        }
        if (username.equals(userLogin.getUsername()) && password.equals(userLogin.getPassword())) {
         //需要一个map集合  传什么 解析出来什么   一般传的是登录用户的id  我们传1
            HashMap<String, Object> map = new HashMap<>();
            map.put(MessageConstant.LOGIN_ID, userLogin.getId());
            String token = JwtUntils.CreateJwt(map, jwtProperties.getSecretkey());
            //设置redis缓存为1000天
            redisTemplate.opsForValue().set(MessageConstant.TOKEN,token,1000,TimeUnit.DAYS);
            return Result.success(token);
        }
        return Result.error("未知错误");
    }

}

interceptor方法

@Component
@RequiredArgsConstructor
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {
    private  final JwtProperties jwtProperties;
    private  final RedisTemplate redisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//主要解析到请求头之后的token 之后  进行一次 的登录请求校验  如果不是登录请求 而是其他的方法  我们就进行放行
        String requestURI = request.getRequestURI();
        if (requestURI.contains("/userLogin")) {
            return  true;
        }
        //获取请求头的 token
//        String token = request.getHeader(jwtProperties.getTokenname());
        String redisToken = (String)redisTemplate.opsForValue().get(MessageConstant.TOKEN);
        log.info("token:{}",redisToken);
        if (redisToken != null ) {
            //进行jwt的解析
            try {
                Claims claims = JwtUntils.parseJwt(redisToken, jwtProperties.getSecretkey());
                //每次 访问其他资源的时候 都把token更新
                redisTemplate.expire(MessageConstant.TOKEN, 1000, TimeUnit.DAYS);
                String loginId = claims.get(MessageConstant.LOGIN_ID).toString();
                ThreadContext.setCurrentId(Long.valueOf(loginId));
                log.info("当前用户的id:{}", ThreadContext.getCurrentId());
                return true;
            } catch (Exception e) {
                response.setStatus(401);
                log.info("{}",e.getMessage());
                return false;
            }
        }
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
       return  false;

    }
}

下面我们进行接口测试

接口测试

我们先看我们redis中现在是没有存token的

我们进行登录

然后再去看我们redis中的token数据

过期时间是八千多万秒,然后我们随便进行一个查询员工的请求

 再看redis中token的缓存时间

又变回来了

  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三氧化真

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值