方案一:

假如配置的过期时间为1小时

cache 存key, value: key为token value 当前时间

cache可以是内存,也可以是redis

前端登录成功后,后端颁发token,前端每次带着token来后端请求,

后端写个拦截器,首先验证token、此次从缓存中拿到token并进行自动续期,即从新算时间,可理解为设置当前时间,

那什么时候token才会失效呢?

写个定时任务,定时去检查cache中过期的token,发现时间已经大于1小时,就从cache中移除,下次前端带着token来后端请求,经过拦截器时,为什么没有自动续期呢?原因是此次缓存中已不存在token为key的缓存了,即可抛出token失效。

方案二:转: https://zhuanlan.zhihu.com/p/163053370

前言

在前后端分离的开发模式下,前端用户登录成功后后端服务会给用户颁发一个jwt token。前端(如vue)在接收到jwt token后会将token存储到LocalStorage中。

后续每次请求都会将此token放在请求头中传递到后端服务,后端服务会有一个过滤器对token进行拦截校验,校验token是否过期,如果token过期则会让前端跳转到登录页面重新登录。

因为jwt token中一般会包含用户的基本信息,为了保证token的安全性,一般会将token的过期时间设置的比较短。

但是这样又会导致前端用户需要频繁登录(token过期),甚至有的表单比较复杂,前端用户在填写表单时需要思考较长时间,等真正提交表单时后端校验发现token过期失效了不得不跳转到登录页面。

如果真发生了这种情况前端用户肯定是要骂人的,用户体验非常不友好。本篇内容就是在前端用户无感知的情况下实现token的自动续期,避免频繁登录、表单填写内容丢失情况的发生。

实现原理

jwt token自动续期的实现原理如下:

  1. 登录成功后将用户生成的 jwt token 作为key、value存储到cache缓存里面 (这时候key、value值一样),将缓存有效期设置为 token有效时间的2倍。
  2. 当该用户再次请求时,通过后端的一个 jwt Filter 校验前端token是否是有效token,如果前端token无效表明是非法请求,直接抛出异常即可;
  3. 根据规则取出cache token,判断cache token是否存在,此时主要分以下几种情况:
  • cache token 不存在这种情况表明该用户账户空闲超时,返回用户信息已失效,请重新登录。
  • cache token 存在,则需要使用jwt工具类验证该cache token 是否过期超时,不过期无需处理。过期则表示该用户一直在操作只是token失效了,后端程序会给token对应的key映射的value值重新生成jwt token并覆盖value值,该缓存生命周期重新计算。

实现逻辑的核心原理:前端请求Header中设置的token保持不变,校验有效性以缓存中的token为准。

代码实现(伪码)

  1. 登录成功后给用户签发token,并设置token的有效期
...
SysUser sysUser = userService.getUser(username,password);
if(null !== sysUser){String token = JwtUtil.sign(sysUser.getUsername(),
sysUser.getPassword());
}
...public static String sign(String username, String secret) {//设置token有效期为30分钟Date date = new Date(System.currentTimeMillis() + 30 * 60 * 1000);//使用HS256生成token,密钥则是用户的密码Algorithm algorithm = Algorithm.HMAC256(secret);// 附带username信息return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
}
  1. 将token存入redis,并设定过期时间,将redis的过期时间设置成token过期时间的两倍
Sting tokenKey = "sys:user:token" + token;
redisUtil.set(tokenKey, token);
redisUtil.expire(tokenKey, 30 * 60 * 2);
  1. 过滤器校验token,校验token有效性
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {//从header中获取tokenString token = httpServletRequest.getHeader("token")if(null == token){throw new RuntimeException("illegal request,token is necessary!")}//解析token获取用户名String username = JwtUtil.getUsername(token);//根据用户名获取用户实体,在实际开发中从redis取User user = userService.findByUser(username);if(null == user){throw new RuntimeException("illegal request,token is Invalid!")}//校验token是否失效,自动续期if(!refreshToken(token,username,user.getPassword())){throw new RuntimeException("illegal request,token is expired!")}...
}
  1. 实现token的自动续期
public boolean refreshToken(String token, String userName, String passWord) {Sting tokenKey = "sys:user:token" + token ;String cacheToken = String.valueOf(redisUtil.get(tokenKey));if (StringUtils.isNotEmpty(cacheToken)) {// 校验token有效性,注意需要校验的是缓存中的tokenif (!JwtUtil.verify(cacheToken, userName, passWord)) {String newToken = JwtUtil.sign(userName, passWord);// 设置超时时间redisUtil.set(tokenKey, newToken) ;redisUtil.expire(tokenKey, 30 * 60 * 2);}return true;}return false;
}
...public static boolean verify(String token, String username, String secret) {try {// 根据密码生成JWT效验器Algorithm algorithm = Algorithm.HMAC256(secret);JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();// 效验TOKENDecodedJWT jwt = verifier.verify(token);return true;} catch (Exception exception) {return false;}
}

本文中jwt的相关操作是基于 com.auth0.java-jwt 实现,大家可以通过阅读原文获取 JwtUtil 工具类。

小结

jwt token实现逻辑的核心原理是 前端请求Header中设置的token保持不变,校验有效性以缓存中的token为准,千万不要直接校验Header中的token。实现原理部分大家好好体会一下,思路比实现更重要!

token 自动续期的方案相关推荐

  1. JWT 实现登录认证 + Token 自动续期方案

    前言 过去这段时间主要负责了项目中的用户管理模块,用户管理模块会涉及到加密及认证流程.今天就来讲讲认证功能的技术选型及实现.技术上没啥难度当然也没啥挑战,但是对一个原先没写过认证功能的菜鸡来说也是一种 ...

  2. 登陆认证方案比较(JWT 登录认证 + Token 自动续期)

    概述 用户管理模块会涉及到加密及认证流程,今天就来讲讲认证功能的技术选型及实现. 技术选型 要实现认证功能,很容易就会想到 JWT 或者 session,但是两者有啥区别?各自的优缺点?应该 Pick ...

  3. token 过期后,如何自动续期?

    JWT token的 payload 部分是一个json串,是要传递数据的一组声明,这些声明被JWT标准称为claims. JWT标准里面定义的标准claim包括: iss(Issuser):JWT的 ...

  4. 【证书】certbot 工具,自动 letencrypt 通配符证书自动续期(renew)

    功能 使用 certbot 工具,为不能自动给 letencrypt 通配符证书自动续期(renew)而烦恼吗?这个工具能够帮忙! 不管是申请还是续期,只要是通配符证书,只能采用 dns-01 的方式 ...

  5. jwt token注销_JWT生成token及过期处理方案

    ## 业务场景 在前后分离场景下,越来越多的项目使用token作为接口的安全机制,APP端或者WEB端(使用VUE.REACTJS等构建)使用token与后端接口交互,以达到安全的目的.本文结合sta ...

  6. docker自动续期Freenom域名,配置邮件提醒

    1.引言 众所周知,Freenom是地球上唯一一个提供免费顶级域名的商家,不过需要每年续期,每次续期最多一年.利用docker自动续期Freenom域名,并配置邮件提醒 1.1 项目地址 freeno ...

  7. acme自动化---免费SSL证书申请并自动续期

    开始自己弄了一遍自动续期的,测试了一下,本来想过段时间看看效果后再写这篇文章的,但是有效期三个月,现在等了一个多月了,我自己的网站申请的免费证书过期了,这个测试自动续期的还有一个多月,据说到一个月的时 ...

  8. Redis 分布式锁如何自动续期

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/upstream480/article/ details/121578638 Redis 实现分布 ...

  9. 轻舟智航发布Driven-by-QCraft第三代自动驾驶硬件方案

    如何保证 L4 级自动驾驶系统的普适性,同时找到自动驾驶车辆成本.规模化之间的平衡点?近日,此前已经在自动驾驶网约巴士(Robobus)领域打出声量的轻舟智航推出了全新的 Driven-by-QCra ...

  10. windows 自动备份mysql方案

    windows 自动备份mysql方案 1.bat cd C:\Program Files\Huweishen.com\PHPWEB\MySQL Server 5.5\bin mysqldump -u ...

最新文章

  1. Flask-Migrate
  2. 成功解决r2_score函数输出值始终为0的情况
  3. How far away ?
  4. Anaconda 中no module named cv2的解决办法
  5. for命令linux,linux中的for命令
  6. MySQL 创建联结
  7. 如何理解5G空口(NR)?
  8. 袁玉玮:简介人工智能在基金界的应用 (一)
  9. mysql5.0驱动_mysql5.0驱动包
  10. 有哪些好用的在线条形码生成器?
  11. 让程序像人一样的去批量下载歌曲?Python采集付费歌曲
  12. [UWP]如何实现UWP平台最佳图片裁剪控件
  13. 20190904_chip-seq/ ATAC-seq/DAP-seq 原理理解
  14. java证明角谷猜想_Java程序(角谷猜想,applet) -
  15. 你想要的宏基因组-微生物组知识全在这(2021.12)
  16. Win32 OpenGL 编程(1)Win32下的OpenGL编程必须步骤
  17. 用html5看板娘,记在nuxt.js中引入一个萌哒哒的看板娘(Live2d模型)
  18. Unity大场景数据加载及优化方案
  19. 3DUnity汽车尾气模拟
  20. UML类图示例一张:公司结构

热门文章

  1. 千年db服务器注册,千年服务器架设说明.doc
  2. Docker基础知识及安装部署
  3. 铁汁!高并发这些东西都是虚拟的,你都理解透彻了嘛?(高并发目标/高并发构架演进/分布式/面向服务架构/高并发平台)
  4. 如何更改您的Apple ID电子邮件地址
  5. C# Message类的属性Msg所关联的消息ID
  6. webStrom找回删除的文件
  7. gae mysql_国内几大云服务引擎 BAE、SAE 与 GAE 优劣对比
  8. GAE—图自编码器/Graph RNN/Graph RL
  9. 3、男人长得丑,除了知识还需要些什么?
  10. 文化财经SAR指标计算(二)