前端JWT token维护方案(补充)

一、前言

JWT的Token登录认证是目前比较流行的跨域认证解决方案。原理在于将认证信息保存在客户端,下次访问其他页面时,需要从客户端传递认证信息回服务器端

具体实现如下:

1.登录成功,后端生成带有access_token并返回前端,前端将access_token保存到本地(cookie或者localStorage,cookie遇跨域问题可以设置withCredentials)

2.其他请求将使用access_token请求接口资源,后端access_token校验通过则调用接口成功;如果token超时,客户端携带refresh_token调用接口获取新的access_token。

3.后端接受刷新access_token的请求后,检查refresh_token是否过期。如过期,拒绝刷新,客户端收到该状态后,跳转到登录页;如无过期,客户端携带新的access_token重新调用上面的资源接口。

 

二、难点

1.同时有多个异步接口请求,当其中一个接口发现access_token过期,其他接口如何处理

 

三、解决方案

前端拦截响应数据,并发起刷新token的请求,拿到最新的token保存到本地,并去进行刚刚未请求成功的接口。在刷新token请求期间,其他异步请求将返回一个未执行resolve的promise,并把resolve

压入数组中等待执行,token刷新成功后遍历数组直接执行

 

四、代码实现

import { refreshToken } from '../apis/login'

// 是否正在刷新的标记

let isRefreshing = false;

// 每一项将是一个待执行的函数形式

let requests = [];

// response interceptor

service.interceptors.response.use(

    async (response) => {

      const res = response.data

      switch (res.code) {

        case 4007:

          if (!isRefreshing) {

            isRefreshing = true

            //刷新token方法,等待刷新token方法执行返回后在执行后面的代码

            const { data } = await refreshToken({

              token: getToken('token')

            })

            setToken('token', data.token)

            /* 重新发送上一条请求(这条请求不会再下的else代码中拦截),await不需要加,无需异步完成以后在执行后面函数 */

            requests.forEach(request => request());

            requests = [];

            isRefreshing = false;

            return service({

              ...response.config

            });

          else {

            // 正在刷新token,将返回一个未执行resolve的promise

            // 拦截其他所有的请求,使其处于一个未执行的状态,只有当刷新token请求返回以后,再执行拦截的所有请求

            return new Promise((resolve) => {

              // 将resolve放进数组,用一个函数形式来保存,等token刷新后直接执行

              requests.push(() => {

                resolve(service({

                  ...response.config

                }))

              })

            })

          }

      }

    }

)

 

export default service

 

五、其他解决方案

经过思考和与后端同事的沟通后,发现在后端用“锁”也能实现类似功能,并且如果项目涉及多客户端,用后端实现可能会更优,后续也会和后端同事继续沟通和探讨。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值