基于无状态的token刷新机制

近日在捣鼓token的时候遇到了很多问题,一个比较突出的问题就是,token是无状态的,要把它变为有状态的就失去了本来的意义,但是又如何为token做有效期的更新呢?如何让用户每次操作页面的时候token自动更新呢?如何避免用户在操作时不会自动token失效呢?

在查阅了很多的资料后,确定了一个比较合适的方法,使用refresh_token机制,而不是使用session和redis这种标识为有状态,况且能做到手机端和PC端的适配.

token+refresh_token流程图

基于无状态的token刷新机制_第1张图片

refresh_token处理

既然refresh_token是和token有密切关联的,那么就要在refresh_token的生成中加密,不过要我们再自己去建一个refresh_token的框架那未免是太小题大做了。生成token的机制里就有现成的方式,所以refresh_token的处理我就总结了两个方法。
方法一:在token里放上refresh_token的标识
在token的载荷payload里加上当前用户的refresh_token标识,此标识可以是refresh_token的到期时间:

payload = {'refresh_token':'201908141858'}           # 载荷里添加refresh_token的信息

加入此时间的目的是,在以后的token验证中,token作为我们验证的大前提,只要token验证通过了,那么refresh_token就无需再验证。但在验证token的时候,由于我们放了refresh_token的到期时间,就可以通过时间的比对判断refresh_token是否过期,如果过期则重新生成一个新的refresh_token放在返回头里返回给客户端,这样token和refresh_token就可以在用户有操作的情况下一直绑定着,不会出现说用户刚操作没多久,token到期了就会忽然掉线而操作不了的情况。但如果token验证到期了,就去验证refresh_token,如果没过期就可以进行事务请求访问处理程序,然后在此次请求的响应头中加入新生成的token返回给客户端。如果refresh_token也过期了,那就是真的GG了,就需要客户端重新登陆了。

方法二:同时检验token和refresh_token
首先,在每个用户登陆的时候,前端处理事务的返回头中应该包括如下:

headers={'token':'','refresh_token':''}

同样,refresh_token使用和token一样的生成方式,在refresh_token里加入user_id(用户的id)来做token的标识,以便于下次验证token失效的时候生成token。主要验证流程如下:

if tokenVerify and refresh_tokenVerify:  #如果token和refresh_token的验证都通过了
	print(‘验证都通过')
elif tokenVerify and not refresh_tokenVerify:  #如果token验证通过和refresh_token未通过
	print('token验证通过,refresh_token验证未通过')
	new_refresh_token = refresh_tokenGenerate()    # 返回头里返回一个新的refresh_token
elif not tokenVerify and refresh_tokenVerify:  # 如果token验证未通过,refresh_token的验证通过了
	print('token验证未通过,refresh_token的验证通过')
	new_token = tokenGenerate()  # 返回头里返回一个新的token
else:   # 如果两个验证都未通过
	print ('验证都未通过')
	return False

1.验证都通过的时候不需要对token和refresh_token进行任何修改;
2.token验证通过,refresh-token验证未通过时生成新的refresh_token给前端使用;
3.token验证未通过,refresh_token验证通过时生成新的token给前端使用;
4.验证都未通过则重新登陆。

无论是方法一还是方法二,refresh_token的有效期最好设置长一些,可以是1个月,而token的有效期则可以设置得短一些。

你可能感兴趣的:(token)