JWT 设置token过期时间无效的解决

 更新时间:2022年07月08日 15:24:56   作者:changerzhuo  
这篇文章主要介绍了JWT 设置token过期时间无效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

JWT 设置token过期时间无效

原因

设置超时时间的顺序有误, 应调用setClaims()方法设置claims属性。

在调用setExpiration()方法设置超时时间。

Date expiresDate = new Date(System.currentTimeMillis() + expire_time);// expire_time为token有效时长, 单位毫秒

错误顺序示例: 

JwtBuilder result = Jwts.builder()
                .setExpiration(date) // 超时时间设置在 setClaims之前
        .setClaims(claims) 
        .signWith(SignatureAlgorithm.HS256, Constants.BASE64SECRET);

正确顺序示例:

JwtBuilder result = Jwts.builder()
        .setClaims(claims) // 先调用setClaims, 在调用setExpiration
        .setExpiration(date)
        .signWith(SignatureAlgorithm.HS256, Constants.BASE64SECRET);


 

原因分析

//io.jsonwebtoken.impl.DefaultJwtBuilder#setExpiration 中代码
    @Override
    public JwtBuilder setExpiration(Date exp) {
        if (exp != null) {
            // 设置的时间不为空,就调用ensureClaims方法
            ensureClaims().setExpiration(exp);
        } else {
            if (this.claims != null) {
                //noinspection ConstantConditions
                this.claims.setExpiration(exp);
            }
        }
        return this;
    }
 
 
// io.jsonwebtoken.impl.DefaultJwtBuilder#ensureClaims 中代码
    protected Claims ensureClaims() {
        // 如果claims为null, 则创建新的示例。 此处没有问题
        if (this.claims == null) {
            this.claims = new DefaultClaims();
        }
        return this.claims;
    }
 
// io.jsonwebtoken.impl.DefaultJwtBuilder#setClaims(io.jsonwebtoken.Claims) 中代码
    @Override
    public JwtBuilder setClaims(Claims claims) {
        // 直接给claims赋值, 这里个操作覆盖了之前设置的超时时间,
        // 导致最终构造token时, 没有设置超时时间
        this.claims = claims;
        return this;
    }

JWT token过期自动续期解决方案

JWT

JWT全称JSON Web Token,由三部分组成header(头部,用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等)、payload(载荷,就是存放有效信息的地方,在这一部分中存放过期时间)和signature(签证,签证信息)。

token

token就是后端生成的JWT字符串值,在前后端分离中,token是前端访问后端接口的合法身份、权限的凭证。

token过期刷新方案

1、单点登录

用户登录,后端验证用户成功之后生成两个token,这两个token分别是access_token(访问接口使用的token)、refresh_token(access_token过期后用于刷续期的token,注意设置refresh_token的过期时间需比access_token的过期时间长),后端将用户信息和这两个token存放到redis中并返回给前端。

前端在获取到登录成功返回的两个token之后,将之存放到localStorage本地存储中。

2、接口请求

前端封装统一接口请求函数、token刷新函数,在请求成功之后对返回结果进行校验,如果token过期,则调用token刷新函数请求新的token.

后端在接收到token刷新请求之后通过结合redis中存放的用户信息、token和refresh_token对请求参数进行验证,验证通过之后生成新的token和refresh_token存放到redis中并返回给前端。至此完成token刷新。

3、多请求应对

所谓多请求,就是指在短时间内同时发生多个请求,如果此时token已经过期,那么这些请求都会出现token过期请求失败的情况。

为了避免反复刷新token,需要设置一个刷新token的开关isRefresh,当一个请求出现token过期的时候,这个时候会调用token刷新函数,与此同时关闭开关将isRefresh的值设置为false,避免后续请求去调用token刷新函数。

当发现token过期时,咱们将请求延缓到token刷新之后再重新执行请求,这里采用Promise函数,把每一个token失效的请求都存到一个Promise函数集合里面,当token刷新之后打开开关将isRefresh的值设置为true,然后批量执行Promise函数集合里面的Promise函数,返回请求结果。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring security用户URL权限FilterSecurityInterceptor使用解析

    Spring security用户URL权限FilterSecurityInterceptor使用解析

    这篇文章主要介绍了Spring security用户URL权限FilterSecurityInterceptor使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Go Java算法之找不同示例详解

    Go Java算法之找不同示例详解

    这篇文章主要为大家介绍了Go Java算法之找不同示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 解决springboot3:mybatis-plus依赖错误:org.springframework.beans.factory.UnsatisfiedDependencyException

    解决springboot3:mybatis-plus依赖错误:org.springframework.beans.fac

    这篇文章主要介绍了解决springboot3:mybatis-plus依赖错误:org.springframework.beans.factory.UnsatisfiedDependencyException问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • java中的实体类时间格式化

    java中的实体类时间格式化

    这篇文章主要介绍了java中的实体类时间格式化方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java Web开发中过滤器和监听器使用详解

    Java Web开发中过滤器和监听器使用详解

    这篇文章主要为大家详细介绍了Java中的过滤器Filter和监听器Listener的使用以及二者的区别,文中的示例代码讲解详细,需要的可以参考一下
    2022-10-10
  • javaFX实现五子棋小游戏

    javaFX实现五子棋小游戏

    这篇文章主要为大家详细介绍了javaFX实现五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • MyBatisPlus 自定义sql语句的实现

    MyBatisPlus 自定义sql语句的实现

    这篇文章主要介绍了MyBatisPlus 自定义sql语句的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Shell重启SpringBoot项目脚本的示例代码(含服务守护)

    Shell重启SpringBoot项目脚本的示例代码(含服务守护)

    本文介绍了如何使用 Bash 脚本来管理和守护运行服务,将展示一个示例脚本,该脚本可以停止、启动和守护运行一个服务,并提供了相应的解释和用法说明,文章通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • Java2 JDK安装和配置教程

    Java2 JDK安装和配置教程

    这篇文章主要为大家详细介绍了Java2 JDK安装和配置教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • Java由浅入深带你了解什么是包package

    Java由浅入深带你了解什么是包package

    为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间,一个包(package)可以定义为一组相互联系的类型(类、接口、枚举和注释),为这些类型提供访问保护和命名空间管理的功能
    2022-03-03

最新评论