如使用Lavarel/lumen中jwt认证,必然会涉及3个参数:JWT_TTL,JWT_REFRESH_TTL,JWT_BLACKLIST_GRACE_PERIOD,他们的作用分别如下:
JWT_TTL: 获得访问权限的token 有效的时间长度(以分钟为单位),默认为60分钟,也可以将其设置为空,以产生永不过期的token。
JWT_REFRESH_TTL:可刷新的时间长度(以分钟为单位)。默认的时间为 2 周。大概意思就是如果用户有一个 访问token,那么他可以带着他的访问token ,过来领取新的token,直到 2 周的时间后,他便无法继续刷新了,需要重新登录。
JWT_BLACKLIST_GRACE_PERIOD:当多个并发请求使用相同的JWT进行时, 由于 token 的刷新 ,其中一些可能会失败,以秒为单位设置请求时间以防止并发的请求失败。
网上有关JWT_BLACKLIST_GRACE_PERIOD的解释不多,通过摸索实践,发现这个参数对于并发请求关键:
如果该值默认为0,token刷新后,旧token立即失效,但往往同时有多个并发请求,比如A、B、C三个同时并发,token时间超过JWT_TTL但在JWT_REFRESH_TTL内,如果先执行A,刷新后得到新token,B、C都附带旧token,这个时候再去刷新token就会报已列入黑名单的错误,JWT_BLACKLIST_GRACE_PERIOD(比如设置30)的作用就是保证B、C的旧token在设置30秒时间内是有效的,可以继续刷新获得新token,继续执行,不报错。
但仍有一个问题,A、B、C三个旧token同时有效,并发同时获得三个新token,给jwt造成资源浪费,如果不介意,也没有问题。
如果想要并发只刷新得到一个token,不能仅靠JWT_BLACKLIST_GRACE_PERIOD来控制,需要另外逻辑控制。
主要逻辑就是:A、B、C其中一个请求刷新后,将新token存入数据库或者redis缓存,其他请求先访问数据库或者redis缓存是否存在新token,如果存在,将新token取出,设置在本次请求的header中,用新的token保证继续执行。这样就确保了新token只有一个,其他并发请求通过新token完成各自请求继续前行,不出错。