dolyw/ShiroJwt

Token刷新并发处理

dolyw opened this issue · 7 comments

dolyw commented

同时多个请求,第一个请求刷新了 Token,后面的请求还是携带的刷新前的旧 Token 就无法通过,该怎么处理

dolyw commented

前端使用axios解决

同时发起多个请求时,其他接口如何重试,两个接口几乎同时发起和返回,第一个接口会进入刷新 Token 后重试的流程,而第二个接口需要先存起来,然后等刷新 Token 后再重试。同样,如果同时发起三个请求,此时需要缓存后两个接口,等刷新 Token 后再重试。由于接口都是异步的,处理起来会有点麻烦。

当第二个过期的请求进来,Token 正在刷新,我们先将这个请求存到一个数组队列中,想办法让这个请求处于等待中,一直等到刷新 Token 后再逐个重试清空请求队列。

那么如何做到让这个请求处于等待中呢?为了解决这个问题,我们得借助 Promise。将请求存进队列中后,同时返回一个 Promise,让这个 Promise 一直处于 Pending 状态(即不调用 resolve),此时这个请求就会一直等啊等,只要我们不执行 resolve,这个请求就会一直在等待。当刷新请求的接口返回来后,我们再调用 resolve,逐个重试。

dolyw commented

后端使用Redis解决

同时多个接口请求,第一个接口刷新了 Token,后面的请求还是携带的刷新前的旧 Token

后端要解决这个情况,应该再添加一个刷新 Token 的过渡期,在刷新 Token 的时候,在 Redis 同时设置一条过渡期数据,视情况设置 15S 过期(这个时间看情况设置),然后认证的时候先判断这个 Token 是不是还在过渡期内,是的话就直接放行通过。

大概的意思的刷新Token后,应该再添加一个刷新 Token 的过渡期,在 Redis 同时设置一条过渡期数据,设置 15S 过期(这个时间看情况设置),然后首先判断下Redis中是否存在这个Token,存在就放行,这样同一时间的请求就都可以通过了。

示例代码: https://github.com/dolyw/ShiroJwt/tree/dev

示例代码中并发请求判断在有效时间内之后,登陆依然用的是旧的token(this.getSubject(request,response).login(jwtToken)),这样shiro不是会继续报出token失效的异常吗,依然会登陆不成功

dolyw commented

示例代码中并发请求判断在有效时间内之后,登陆依然用的是旧的token(this.getSubject(request,response).login(jwtToken)),这样shiro不是会继续报出token失效的异常吗,依然会登陆不成功

没理解你的意思,能详细贴下代码,和你思考的流程吗,可以加下QQ群交流: 779168604

dolyw commented

示例代码中并发请求判断在有效时间内之后,登陆依然用的是旧的token(this.getSubject(request,response).login(jwtToken)),这样shiro不是会继续报出token失效的异常吗,依然会登陆不成功

理解你意思了,不是说了加个过渡期吗,这个过渡期内Token就是有效的啊

token过期后,如果同时发出多个请求,并且有的请求的接口比刷新token的接口慢的话,就会刷新多次 token

大佬 Token被盗用 怎么处理啊