对 Token 进行刷新续期,我们要解决并发请求导致重复刷新 Token 的问题,这也是设计刷新 Token 的难点。这里我会分别介绍前端和后端各自的处理方案。

后端方案:利用 Redis 缓存

当同时发起多个请求时,第一个接口刷新了 Token,后面的请求仍然能通过请求,且不造成 Token 重复刷新。那么,后端在用户第一次登录时,需要将生成的 Token 数据(token 和 createTime)缓存一份到 Redis 中。

当 Token 过期时,重新生成新的 Token 数据并更新 Redis 缓存,同时在 Redis 中设置一条 Token 过渡数据并设置一个很短的过期时间(比如 30s)。如果后面的请求发现 Token 已经被刷新了,就判断 Redis 中是否存在 Token 过渡数据,存在就放行,这样同一时间的请求都可以通过。

源码地址:https://github.com/yifanzheng/spring-security-jwt/tree/refresh-token-redis

Token 刷新流程图

前端方案:请求拦截

由于前端请求都是异步的,只有一个请求的时候,刷新 Token 是比较好处理的,但并发请求下刷新 Token 处理起来有点麻烦。我们需要考虑在多个请求几乎同时发起并且 Token 都失效的情况,当第一个请求进入 Token 刷新流程时,其他请求必须等待第一个请求完成 Token 刷新后再使用新 Token 进行重试。
简单地讲,就是同一时间有多个请求且 Token 都失效,在第一个请求进行 Token 刷新时,其他请求必须处于等待状态,直到 Token 刷新完成,才能携带新 Token 进行重试。

下面,我使用了 Angular 的请求拦截器,利用 BehaviorSubject 进行 Token 刷新状态的监听,当 Token 刷新成功,放行后面的请求进行重试。

除此之外,前端还可以利用 Promise,将请求存进队列中后,同时返回一个 Promise,让这个 Promise 一直处于 Pending 状态(即不调用 resolve),此时这个请求就会一直等待,只要我们不执行 resolve,这个请求就会一直在等待。当刷新 Token 的请求完成后 ,我们再调用 resolve,逐个重试。

Github 地址:https://github.com/yifanzheng/spring-security-jwt/tree/refresh-token-frontend

Angular 代码示列

import { Injectable } from "@angular/core";
import {HttpEvent,HttpInterceptor,HttpHandler,HttpRequest,HttpErrorResponse
} from "@angular/common/http";
import { throwError, Observable, BehaviorSubject, of } from "rxjs";
import { catchError, filter, finalize, take, switchMap, mergeMap } from "rxjs/operators";@Injectable()
export class AuthInterceptor implements HttpInterceptor {private refreshTokenInProgress = false;private refreshTokenSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {if (!req.headers.has("Content-Type")) {req = req.clone({headers: req.headers.set("Content-Type", "application/json")});}// 统一加上服务端前缀let url = req.url;if (!url.startsWith('https://') && !url.startsWith('http://')) {url = "./" + url;}req = req.clone({ url });req = this.setAuthenticationToken(req);return next.handle(req).pipe(mergeMap((event: any) => {// 若一切都正常,则后续操作return of(event);}),catchError((error: HttpErrorResponse) => {// 当是 401 错误时,表示 Token 已经过期,需要进行 Token 刷新if (error && error.status === 401) {if (this.refreshTokenInProgress) {// 如果 refreshTokenInProgress 为 true,我们将等到 refreshTokenSubject 是 true 时,才可以再次重试该请求// 这表示刷新 Token 动作已完成,新 Token 已准备就绪return this.refreshTokenSubject.pipe(filter(result => result),take(1),switchMap(() => next.handle(this.setAuthenticationToken(req))));} else {this.refreshTokenInProgress = true;// 将 refreshTokenSubject 设置为 false,以便后面的请求调用时将处于等待状态,直到检索到新 Token 为止this.refreshTokenSubject.next(false);return this.refreshToken().pipe(switchMap((newToken: string) => {this.refreshTokenSubject.next(true);// 重新设置新的 TokenlocalStorage.setItem("token", newToken);return next.handle(this.setAuthenticationToken(req));}),// 当刷新 Token 请求完成后,需要将 refreshTokenInProgress 设置为 false,用于下次刷新 Tokenfinalize(() => (this.refreshTokenInProgress = false)));}} else {return throwError(error);}}));}private refreshToken(): Observable<any> {// 这里需要换成实际的 Token 刷新接口return of("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzdGFyIiwicm9sZSI6WyJST0xFX1VTRVIiXSwiaXNzIjoic2VjdXJpdHkiLCJpYXQiOjE2MDY4MjczMDAsImF1ZCI6InNlY3VyaXR5LWFsbCIsImV4cCI6MTYwNjgzNDUwMH0.Hiq2DsH6j4XFd_v87lDWGlYembTLck7DjMLRLWdyvOo");}private setAuthenticationToken(request: HttpRequest<any>): HttpRequest<any> {return request.clone({headers: request.headers.set("Authorization", "Bearer " + localStorage.getItem("token"))});}
}

axios token失效刷新token怎么重新请求_Token 刷新并发处理解决方案相关推荐

  1. ajax异步提交局部刷新页面,ajax异步请求定时刷新局部页面

    用户提问 $(document).ready(function () { $.ajax({ type: 'GET', url:'http://localhost:8080/SSM/user/findR ...

  2. java app token 失效_请求时token过期自动刷新token操作

    1.在开发过程中,我们都会接触到token,token的作用是什么呢?主要的作用就是为了安全,用户登陆时,服务器会随机生成一个有时效性的token,用户的每一次请求都需要携带上token,证明其请求的 ...

  3. 微信小程序token过期后重新执行失效的请求封装(用户无感刷新token)

    考虑接口时效性和安全性,后端增设了token验证,确保我们的单个token只使用一次,使用后就立即失效,但是也为了防止在实际进程中异步请求的出现,所以重新封装了请求方法. 要求是在执行某个请求时,如果 ...

  4. token过期后刷新token并重新发起请求

    系统登录成功后,后端返回token和refreshToken,所有请求都携带token,token如果过期接口将返回401,此时前端需要拿着refreshToken去刷新token,刷新后将拿到新的t ...

  5. 使用Axios进行无感刷新Token

    前言 本人在开发项目时,在做登录模块时,参考了oauth2,在用户认证成功后会返回给前端一些令牌相关数据.接下来,再用进行接口请求时,前端根据令牌数据进行一系列的判断,然后做出最好的选择. 举个例子: ...

  6. Vue刷新token,判断token是否过期、失效的最简便的方法

    看了许多小伙伴分享的刷新token和判断token是否失效的方法,个人感觉有些难懂和不够简便.现结合个人开发实践分享一下使用vue axios请求拦截的方法来刷新token和判断token是否过期.失 ...

  7. java 后台自动刷新请求_请求时token过期自动刷新token

    1.在开发过程中,我们都会接触到token,token的作用是什么呢?主要的作用就是为了安全,用户登陆时,服务器会随机生成一个有时效性的token,用户的每一次请求都需要携带上token,证明其请求的 ...

  8. python token过期_请求时token过期自动刷新token

    1.在开发过程中,我们都会接触到token,token的作用是什么呢?主要的作用就是为了安全,用户登陆时,服务器会随机生成一个有时效性的token,用户的每一次请求都需要携带上token,证明其请求的 ...

  9. php token 自动过期,请求时token过期自动刷新token

    1.在开发时这例随时幻近我些如机兼灯近我些如机兼灯过程中,我们都会接触到token,token的作用是什么呢?主要的作用就是为了安全,用户登陆时,服务器会随机生成一个有时效性的token,用户的每一次 ...

  10. axios 登录后设置header_axios如何利用promise无痛刷新token

    需求 最近遇到个需求:前端登录后,后端返回token和token有效时间,当token过期时要求用旧token去获取新的token,前端需要做到无痛刷新token,即请求刷新token时要做到用户无感 ...

最新文章

  1. Azure 服务管理 Cmdlet(1)
  2. 深度学习核心技术精讲100篇(五十四)-阿里文娱多模态视频分类算法中的特征改进
  3. [Aaronyang] 写给自己的WPF4.5 笔记6[三巴掌-大数据加载与WPF4.5 验证体系详解 2/3]
  4. 关于四金计算和工资对照表
  5. HDU ACM 1078 FatMouse and Cheese 记忆化+DFS
  6. 微型计算机除具有计算机的一般特点外,10秋学期《计算机应用基础》第1次在线作业答案免费6/15...
  7. python 二维列表切片_Python中mutable与immutable和二维列表的初始化问题
  8. java方法的重载 编程题,java面试编程题:重载方法
  9. 在Zabbix中添加交换机端口监控
  10. python中判断文本的编码格式
  11. 第十二章:互联网-webbrowser:显示Web页面-使用特定浏览器
  12. fps透视基础-3分钟快速定位矩阵基址-附3D坐标转屏幕坐标算法
  13. 一个霸占程序员休息时间的 APP
  14. magento添加sku_快速提示:如何将优惠券添加到Magento电子商务商店
  15. 9个好用的生命科学研究工具分享
  16. 2021年中国社会客货运输量及周转量情况分析[图]
  17. [附源码]计算机毕业设计JAVAjsp图书借阅系统
  18. Qt编写安防视频监控系统43-图片回放
  19. uniapp 九宫格抽奖功能
  20. 晏子:拒欲不道,恶爱不祥

热门文章

  1. Response.Redirect在新窗口打开
  2. 杭电多校第一场补题-1002 Balanced Sequence
  3. 高德发布十一出行预测:全国高速流量增长7%
  4. 企业从信息化角度解读智慧城市,难以根治城市病
  5. linux安装openssl、swoole等扩展的具体步骤
  6. (十六)企业部分之lvs
  7. GreenDroid 开源UI组件
  8. 运用incremental backup恢复归档GAP的DG-上篇
  9. java result_Result对象 + 统一异常处理
  10. Mybatis原生dao开发方法实现增删改查