js项目中前端如何实现无感刷新token

 更新时间:2023年07月14日 11:22:21   作者:fly_dream  
本文主要介绍了js项目中前端如何实现无感刷新token,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前一阵遇到了一个问题,线上平台有时会出现用户正在使用的时候,突然要用户去进行登录,这样会造成很不好的用户体验,但是当时一直没有好的思路因此搁置了下来;通过零散时间查询资料以及思考,最终解决了这个问题,接下来跟大家分享一下!

环境

  • 请求采用的 Axios V1.3.2。
  • 平台的采用的 JWT(JSON Web Tokens) 进行用户登录鉴权。
    (拓展:JWT 是一种认证机制,让后台知道该请求是来自于受信的客户端;更详细的可以自行查询相关资料)

问题现象

线上用户在使用的时候,偶尔会出现突然跳转到登录页面,需要重新登录的现象。

原因

  • 突然跳转到登录页面,是由于当前的 token 过期,导致请求失败;在 axios 的响应拦截axiosInstance.interceptors.response.use中处理失败请求返回的状态码 401,此时得知token失效,因此跳转到登录页面,让用户重新进行登录。
  • 平台目前的逻辑是在 token 未过期内,用户登录平台可直接进入首页,无需进行登录操作;因此就存在该现象:用户打开平台,由于此时 token 未过期,用户直接进入到了首页,进行其他操作。但是在用户操作的过程中,token 突然失效了,此时就会出现突然跳转到登录页面,严重影响用户的体验感!
    注:目前线上项目中存在数据大屏,一些实时数据的显示;因此存在用户长时间停留在大屏页面,不进行操作,查看实时数据的情况

切入点

  • 怎样及时的、在用户感知不到的情况下更新token
  • token 失效的情况下,出错的请求可能不仅只有一个;当失效的 token 更新后,怎样将多个失败的请求,重新发送?

操作流程

好了!经过了一番分析后,我们找到了问题的所在,并且确定了切入点;那么接下来让我们实操,将问题解决掉。

前要:

1、我们仅从前端的角度去处理。
2、后端提供了两个重要的参数:accessToken(用于请求头中,进行鉴权,存在有效期);refreshToken(刷新令牌,用于更新过期的 accessToken,相对于 accessToken 而言,它的有效期更长)。

1、处理 axios 响应拦截

注:在我实际的项目中,accessToken 过期后端返回的 statusCode 值为 401,需要在axiosInstance.interceptors.response.useerror回调中进行逻辑处理。

// 响应拦截
axiosInstance.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    let {
      data, config
    } = error.response;
    return new Promise((resolve, reject) => {
      /**
       * 判断当前请求失败
       * 是否由 toekn 失效导致的
       */
      if (data.statusCode === 401) {
         /**
         * refreshToken 为封装的有关更新 token 的相关操作 
         */
        refreshToken(() => {
          resolve(axiosInstance(config));
        });
      } else {
        reject(error.response);
      }
    })
  }
)
  • 我们通过判断statusCode来确定,是否当前请求失败是由token过期导致的;
  • 使用 Promise 处理将失败的请求,将由于 token 过期导致的失败请求存储起来(存储的是请求回调函数,resolve 状态)。理由:后续我们更新了 token 后,可以将存储的失败请求重新发起,以此来达到用户无感的体验

2、封装 refreshToken 逻辑

要点:

  • 存储由于token过期导致的失败的请求。
  • 更新本地以及axios中头部的token
  • refreshToken 刷新令牌也过期后,让用户重新登录。
// 存储由于 token 过期导致 失败的请求
let expiredRequestArr: any[] = [];
/**
 * 存储当前因为 token 失效导致发送失败的请求
 */
const saveErrorRequest = (expiredRequest: () => any) => {
  expiredRequestArr.push(expiredRequest);
}
// 避免频繁发送更新 
let firstRequre = true;
/**
 * 利用 refreshToken 更新当前使用的 token
 */
const updateTokenByRefreshToken = () => {
  firstRequre = false;
  axiosInstance.post(
    '更新 token 的请求',
  ).then(res => {
    let {
      refreshToken, accessToken
    } = res.data;
    // 更新本地的token
    localStorage.setItem('accessToken', accessToken);
    // 更新请求头中的 token
    setAxiosHeader(accessToken);
    localStorage.setItem('refreshToken', refreshToken);
    /**
     * 当获取了最新的 refreshToken, accessToken 后
     * 重新发起之前失败的请求
     */
    expiredRequestArr.forEach(request => {
      request();
    })
    expiredRequestArr = [];
  }).catch(err => {
    console.log('刷新 token 失败err', err);
    /**
     * 此时 refreshToken 也已经失效了
     * 返回登录页,让用户重新进行登录操作
     */
    window.location.href = `${HOME_PAGE}/login`;
  })
}
/**
 * 更新当前已过期的 token
 * @param expiredRequest 回调函数,返回由token过期导致失败的请求
 */
export const refreshToken = (expiredRequest: () => any) => {
  saveErrorRequest(expiredRequest);
  if (firstRequre) {
    updateTokenByRefreshToken();
  }
}

总结

经过一波分析以及操作,我们最终实现了实际项目中的无感刷新token,最主要的是有效避免了:用户在平台操作过程中突然要退出登录的现象(尤其是当用户进行信息填写,突然要重新登录,之前填写的信息全部作废,是很容易让人发狂的)。

到此这篇关于js项目中前端如何实现无感刷新token的文章就介绍到这了,更多相关js 无感刷新token内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • js实现使用输入input和改变change事件模拟手动输入

    js实现使用输入input和改变change事件模拟手动输入

    聚焦于JavaScript中的输入模拟技术,本指南将带你探索如何使用input和change事件来创造逼真的手动输入效果,通过简单的代码实现,你将掌握这一实用的技巧,为你的Web应用增添交互的乐趣,需要的朋友可以参考下
    2024-03-03
  • 一文详解MySQL5.7与MySQL8之间的区别

    一文详解MySQL5.7与MySQL8之间的区别

    MySQL作为最常用的开源关系型数据库管理系统之一,一直在不断发展和改进,其中,MySQL 5.7和MySQL 8是两个备受关注的版本,它们之间存在一些关键的差异,本文将深入探讨这两个版本之间的主要差异,需要的朋友可以参考下
    2023-11-11
  • JS如何循环遍历JSON数据

    JS如何循环遍历JSON数据

    这篇文章主要介绍了JS如何循环遍历JSON数据的方法,本文提供了 JS 循环 JSON 数据列,以及 JS 循环遍历 JSON 数据的例子,需要的朋友可以参考下
    2024-01-01
  • jscript读写二进制文件的方法

    jscript读写二进制文件的方法

    这篇文章主要介绍了jscript读写二进制文件的方法,涉及javascript中ActiveXObject对象的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-04-04
  • Bootstrap CSS组件之导航条(navbar)

    Bootstrap CSS组件之导航条(navbar)

    这篇文章主要为大家详细介绍了Bootstrap CSS组件之导航条(navbar),具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • js 事件的传播机制(实例讲解)

    js 事件的传播机制(实例讲解)

    下面小编就为大家带来一篇js 事件的传播机制(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • JavaScript键盘事件常见用法实例分析

    JavaScript键盘事件常见用法实例分析

    这篇文章主要介绍了JavaScript键盘事件常见用法,简单描述了javascript键盘事件的分类、功能,并结合实例形式给出了javascript响应键盘事件相关使用技巧,需要的朋友可以参考下
    2019-01-01
  • js获取文件里面的所有文件名(实例)

    js获取文件里面的所有文件名(实例)

    下面小编就为大家带来一篇js获取文件里面的所有文件名(实例)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 使用JavaScript动态设置样式实现代码及演示动画

    使用JavaScript动态设置样式实现代码及演示动画

    使用onmouseover和onmouseout事件实现不同的效果而且是使用js动态实现,本文有利于巩固你js与css方面的知识,感兴趣的你可以了解下哦,希望本文对你有所帮助
    2013-01-01
  • Javascript File和Blob详解

    Javascript File和Blob详解

    这篇文章主要为大家介绍了Javascript File和Blob,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12

最新评论