“ 我的后台接口服务,是基于JWT来进行身份验证的,一直以来都没有出过问题,但最近在做一个可视化项目时,客户需要这个系统一直在线,但JWT是有过期时效的,虽然我们可以设置一个很大的时间间隔来保证系统在这段时间内可用,但保不准过段时间我们忘了它就过期了...”
我在网上找了一些关于JWT自动刷新延期的资料,大致分为下面几种:
01
—
刷新过期的JWT
这种方式是在token过期时,重新携带过期的token请求刷新token的接口,返回有效的token,并在次调用接口。流程如图(图片来源于网络)
这种方式刷新token意义不大,并且在过期时需要两次调用接口,在出现并发时会造成token失效的问题。
02
—
两个Token
在用户登录系统后,为用户生成2个token,一个用来正常的接口调用,另一个用来在token快到期时提前刷新token,流程如下(图片来源于网络)
03
—
Token配合缓存,定期检查
这种方式是我现在使用的,具体流程为
用户登录后生成token;
服务端设置token有效期为24小时,并放入缓存中,设置缓存有效期为2小时;
用户保存token到本地存储中;
客户端有定时心跳接口,每30分钟检查token;
如果缓存中没有token,通知客户端token失效;
使用jwt检查token是否过期,如果过期同样通知客户端token失效;
使用jwt检查token是否即将过期(距离过期一小时以内),生成新的token返回给客户端,并放入缓存中;
此时新老token都可以正常调用接口,避免并发时老token失效的问题;
示例代码后端
@Override
public String refreshToken(String token) {
token = token.substring(CommonConstant.TOKEN_TYPE_BEARER.length() + 1);
// 检查token是否快过期
Boolean willExpire = JwtTokenUtil.isTokenWillExpire(token);
if (willExpire) {
SysLoginUser sysLoginUser = getLoginUserByToken(token);
//构造jwtPayLoad
JwtPayLoad jwtPayLoad = new JwtPayLoad(sysLoginUser.getId(), sysLoginUser.getAccount());
//生成新token,此时老token同样可用,如果没有刷新则到期后会从缓存在删除
String newtoken = JwtTokenUtil.generateToken(jwtPayLoad);
//缓存token与登录用户信息对应, 默认2个小时
this.cacheLoginUser(jwtPayLoad, sysLoginUser);
// 生成新的token
return newtoken;
}
return null;
}
/**
* 检查如果失效时间在1小时内,则视为token将要过期
* @param token
* @return
*/
public static Boolean isTokenWillExpire(String token) {
try {
Claims claims = getClaimsFromToken(token);
final Date expiration = claims.getExpiration();
Long duration = expiration.getTime() - new Date().getTime();
return duration < 1 * 60 * 60 * 1000;
} catch (ExpiredJwtException expiredJwtException) {
return true;
}
}
文章转载自零天赋 CODING,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。