登录认证:
token双令牌(无感刷新)
无感刷新:用户访问一个网页,只要在七天内有操作,就不需要重新登陆,登录的token就一直被更新,但如果七天都没有任何操作,那就需要重新登陆
仅后端实现:后端每个接口都自定给token续期(token续期过于频繁,高并发下服务器压力大,而且不安全,一旦被捕获但token且拿到接口,岂不是能无限续签)
仅前端实现,后端给token的时间戳(expireTime),告诉前端到期时间,快到期时前端请求给token续期(不足够安全,可能被篡改,依赖客户端控制)
双令牌实现:
access_token短令牌,几个小时的有效期,refresh_token长令牌,好几天的有效期,
所有接口都通过携带access_token判断有无权限,
access_token过期,发起token续期的请求(携带refresh_token作为参数),后端判断refresh_token是否过期,
refresh_token未过期,生成新的refresh_token(每生成一个新的就有好几天有效期,如果一直使用,可以一直延续)和accsess_token给前端,
若refresh_token过期,返回登录过期给前端,前端需要提示用户重新登陆
值得注意的一点是,为了安全,一般不会把access_token放到localStorage,而是存储在 HTTP-only Cookie 中
由后端实现
那么前端如何在请求token续期时取到refresh_token呢?
只需要在发送请求时,config设置withCredentials: true
关于XSS攻击:
refresh_token存储在HTTP-only Cookie 中,通过document.cookie是取不到的,因此xss攻击无效!!!
关于token双令牌的优化:
由于我们关于token续期的逻辑是在请求中封装的,那么一旦用户在access_token失败时发起多个请求,那岂不是会触发多个续签请求?
优化!必须优化!
设置一个请求队列queue,有n个请求都是执行一样的目的
那么只要第一个请求和服务器建立连接了,其他请求都是去队列里等待。
这个请求成功了,告诉其他请求我成功了;
这个请求失败了,告诉其他请求我失败了;
其实不管成功还是失败,最后任务队列都是要被清空的,里面的请求注定无法发送。
参考博文: