基于Token的身份验证的基本过程如下:
1.用户通过用户名和密码发送请求。
2.服务器端程序验证。
3.服务器端程序返回一个带签名的token给客户端。
4.客户端储存token,并且每次访问都携带token到服务器端的。
5.服务端验证token,校验成功则返回请求数据,校验失败则返回错误码跳转重新登录。
使用refresh token的身份验证操作:
但是如果用户在正常操作的过程中,token过期失效了,要求用户重新登录,对用户的体验会很不好。
使用refresh token,可以避免频繁的读写操作。这种方案中,服务端不需要刷新 token 的过期时间,一旦 token 过期,就反馈给前端,前端使用 refresh token申请一个全新 token 继续使用。大大减少了用户重新登录的操作。当然 refresh token也是有有效期的,但是这个有效期就可以长一点了,比如,以天为单位的时间(15天)。
要点:refresh_token必须保存在客户端的服务器上,调用refresh_token的时候一定是从服务器到服务器的访问。
refresh_token多次刷新问题:
当token超时refresh_token未超时,调用refresh_token刷新token时,如果有新的请求,此时也会再次调用refresh_token刷新,产生多次刷新问题。
设置刷新状态处理多次刷新问题,设置刷新状态变量,当调用refresh_token刷新时,更改刷新变量,其他请求此时就会停止调用刷新状态。但是1却会产生新的问题,等待token刷新时产生的请求处理问题。
等待token刷新时产生的请求如果直接不处理或者让用户再次操作,都会对用户的使用产生不好的体验,可以采用存储请求队列的方式,等待token刷新时产生的请求存储到队列中,当token刷新完毕再重新执行。
请求存储的方式虽然解决了等待token刷新时产生的请求处理问题。但是却过于麻烦,还会影响响应时间。
最终解决方案
每次请求时服务器都对token的有效时间进行判断,当token快要过期时,生成新的token返回,记录刷新时间,短时间内只能刷新一次token,这样就解决了多次刷新的问题。
同时由于token的校验是通过token中的有效时间信息来判断,所以旧的token也能持续一段时间使用,就不会产生请求等待问题。
要点:
什么时间判断要生成新的token:推荐token有效时间的一半。至于为什么要设置这么早,这里引入“活跃用户”的概念。
简单来说用户的上一次操作不超过我们规定的时间,那么这个用户就是活跃用户。什么时候需要让用户重新登录和什么时候需要刷新token?一般都是希望活跃用户刷新token,不活跃用户重新登录。
当用户超过token时间未发送新请求,可以认为是不活跃用户,此时再发送请求就会跳转到重新登录,token有效时间可以设长一些,用户也能更好接受。
如果设置token刷新时间太晚,例如token有效时间1小时,50分设为刷新时间的话。当用户一小时49分最后一次操作,那么11分钟后他就需要重新登录才能操作,所以尽量不要设得太晚。