目录
可以试想一下,当你正在奋笔疾书时,突然弹出登录信息已过期提示
样例代码(伪代码,只是过一下处理逻辑)
1.登陆的时候生成token,改为生成两个token,并利用redis分别设置过期时间
2.@AuthValid注解代码
总结
可以试想一下,当你正在奋笔疾书时,突然弹出登录信息已过期提示
为了杜绝这中有害健康行为,就不得不对原有机制改造,
token时间长点?避免不了突然失效的情景
token永不过期?不安全,家被偷了都没发现
这两种情况显然不可行,那就试试普遍使用的自动续期方式,该方式有很多种实现方案,下面这两种较常见
1.token快过期时自动续期,比如还剩半小时的时候,检测到时间不足自动续期
该方案确实完成了自动续期,也可以及时增加时间,但是比如设置的是不足半小时自动续期,那我如果是在剩余35分钟的时候,触发了一次请求,下一次操作是四十分钟后了,这个时候已经过期了,而由于上次检测到该token是四十分钟之前,导致没有及时续期,登录信息已过期,再次发疯
2.双token,生成两个token accessToken(验证)和refreshToken(刷新),验证token过期时间短些,刷新token设置长一点的过期时间,接口请求调用验证token,验证token过期后,如果有刷新token并且没过期,生成一个验证token返回给前端,后续调用新的验证token即可
双token方案比较灵活的处理了几种特殊情况,也是比较常用的,下面举个样例
一个普通管理系统,基于springboot框架。使用了aop中的@AuthValid注解方法,在有该注解的方法前会先执行该注解中的逻辑,一般就是鉴权
样例代码(伪代码,只是过一下处理逻辑)
先介绍下使用的几种常用工具类
redisUtil:通过封装原生redis操作方法,用于便利操作redis的工具类
jwtUtil:jwt生成token的工具,模板网上都差不多
Result():自定义异常处理类
1.登陆的时候生成token,改为生成两个token,并利用redis分别设置过期时间
String jwttoken = jwtUtil.sign(jwtUserBO);
String refreshToken = jwtUtil.signRefreshToken(jwtUserBO);
redisUtil.set(String.format("accesstoken:%s", jwttoken), jwttoken,21600L);
redisUtil.set(String.format("refreshToken:%s",jwttoken), refreshToken,64800L);
2.@AuthValid注解代码
@Around(value = "anyMethod()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
HttpServletRequest request = servletRequestAttributes.getRequest();
String reqUrl = request.getRequestURI();
String token = jwtUtil.getToken();
if (!StringUtils.hasText(token)) {
//请求头没有token,直接退出
log.warn("no login!");
return new Result().buildWithCustomMsg(false, "4300", MessageUtilsNew.get("common.no_logged_in"), null);
}
if (jwtUtil.isTokenExpired(token)) {
String refreshToken = redisUtil.get("refreshToken:"+ token);
if (!StringUtils.hasText(refreshToken) || jwtUtil.isTokenExpired(refreshToken)) {
//refreshtoken为空或者过期,退出登录
return new Result<>().buildWithCustomMsg(false, "4000", MessageUtilsNew.get("epro.token.invalid"), null);
}
//生成新token
String newToken = createNewToken();
//塞到请求头里,这样前端就可以拿到新的token
httpServletResponse.setHeader("Authorization", " " + newToken);
Object proceed = pjp.proceed();
return proceed;
}
当然这种方案前后端需要协调,前端及时更新请求头里的token即可
总结
token自动续期方式 | ||
token定时检查续期 | 方便实现,只需后端更改即可 | 存在未及时续期情况 |
双token验证 | 效率更高,适用的特殊情况更多 | 需要前后端协调更改 |