js无痛刷新Token的实现

yizhihongxing

当我们使用前后端分离的架构时,前端需要向后端服务器发送API请求获取数据,而前端需要在每次请求时,将后端返回的Token设置在请求的Header中。Token是用来验证用户身份的,它的有效期是有限的,过期后需要重新向服务器获取。在这种情况下,我们需要处理Token过期的问题。下面,我将提供一个JS无痛刷新Token的实现的完整攻略:

Step1:在前端存储Token

我们需要在前端存储Token,可以选择将Token存储在SessionStorage或者LocalStorage中。当用户打开网站时,我们需要从SessionStorage或者LocalStorage中获取Token,并将Token设置在请求的Header中。

Step2:拦截HTTP请求

我们需要拦截所有的HTTP请求,检查当前Token是否过期。如果过期了,我们需要刷新Token。

axios.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token')
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  error => {
    Promise.reject(error)
  }
)

Step3:处理Token过期

当我们发现Token过期了,我们需要向服务器发送请求,获取新Token。一般来说,我们需要将旧Token发送到服务器,然后让服务器校验Token的有效性并返回新Token。拿到新Token后,我们需要将新Token存储在LocalStorage中,并将Token设置在请求的Header中。

axios.interceptors.response.use(
  response => {
    return response
  },
  error => {
    const originalRequest = error.config
    if (error.response.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true
      const refreshToken = localStorage.getItem('refreshToken')
      return axios
        .post('/refresh-token', {
          token: localStorage.getItem('token'),
          refreshToken: refreshToken
        })
        .then(response => {
          const token = response.data.token
          localStorage.setItem('token', token)
          originalRequest.headers.Authorization = `Bearer ${token}`
          return axios(originalRequest)
        })
    }
    return Promise.reject(error)
  }
)

上面的代码使用了axios库来发送Token刷新请求。当我们检测到Token过期时,我们会向服务器发送POST请求,请求体会携带旧Token和RefreshToken。服务器会收到请求后校验Token的有效性,如果无效则返回401状态码。在我们收到401状态码的时候,我们会再次发送Token刷新请求,如果刷新Token成功,我们将新Token存储在LocalStorage中,并将Token设置在请求的Header中,然后重新发起请求。

两条示例

下面提供两条在React项目中实现无痛刷新Token的示例代码:

示例1:

import axios from 'axios'

const instance = axios.create({
  baseURL: 'http://localhost:3000/api',
})

instance.interceptors.request.use(function (config) {
  const token = localStorage.getItem('token')
  if (token) {
    config.headers.authorization = `Bearer ${token}`
  }

  return config
})

instance.interceptors.response.use(
  function (response) {
    return response
  },
  function (error) {
    const originalRequest = error.config
    const refreshToken = localStorage.getItem('refreshToken')

    if (error.response.status === 401 && originalRequest.url !== '/login') {
      if (!originalRequest._retry) {
        originalRequest._retry = true
        return axios.post('/refresh-token', { refreshToken }).then(({ data }) => {
          localStorage.setItem('token', data.token)
          localStorage.setItem('refreshToken', data.refreshToken)
          axios.defaults.headers.common['authorization'] = `Bearer ${data.token}`
          return instance(originalRequest)
        })
      }
    }

    return Promise.reject(error)
  }
)

export default instance

示例2:

import axios from 'axios'

const axiosInstance = axios.create({
  baseURL: 'http://localhost:3000/api'
})

axiosInstance.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token')
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  error => Promise.reject(error)
)

axiosInstance.interceptors.response.use(
  response => response,
  async error => {
    const originalRequest = error.config
    if (
      error.response.status === 401 &&
      error.response.data.message === 'Token expired'
    ) {
      const refreshToken = localStorage.getItem('refreshToken')
      const res = await axios.post(
        '/token/refresh',
        { refreshToken }
      )
      if (res.status === 200) {
        localStorage.setItem('token', res.data.access_token)
        localStorage.setItem('refreshToken', res.data.refresh_token)
        axiosInstance.defaults.headers.common[
          'Authorization'
        ] = `Bearer ${res.data.access_token}`
        return axiosInstance(originalRequest)
      }
    }
    return Promise.reject(error)
  }
)

export default axiosInstance

上述两个示例是基于axios库创建的,你可以根据需要选择使用自己喜欢的库。这两个示例实现了当Token过期时,自动刷新Token并重新发送请求的功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js无痛刷新Token的实现 - Python技术站

(1)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • JS实现运动缓冲效果的封装函数示例

    JS实现运动缓冲效果是前端开发中常见的问题之一。我们可以封装一个函数来实现这个效果,方便快捷地进行运动缓冲效果的实现。 函数封装过程 封装函数涉及到一些关键的概念: 运动开始点 运动结束点 运动距离 运动时间 每一帧的运动距离 运动速度 缓冲系数 基于上述概念,简单描述实现运动缓冲效果的封装函数示例的攻略如下: 确定函数参数 封装函数需要定义函数的参数,以便…

    JavaScript 2023年6月11日
    00
  • Js与Jq获取浏览器和对象值的方法

    我们可以使用 JavaScript 和 jQuery 获取浏览器属性和对象值。下面详细讲解 Js 与 Jq 获取浏览器属性和对象值的方法。 获取浏览器属性 我们可以获取浏览器的宽度、高度、名称、版本等属性。下面是获取浏览器属性的方法: 使用原生 JavaScript 获取浏览器宽度和高度 let width = window.innerWidth; let …

    JavaScript 2023年6月11日
    00
  • JavaScript中常见的字符串操作函数及用法汇总

    JavaScript中常见的字符串操作函数及用法汇总 JavaScript中有很多字符串操作函数,这篇攻略将会讲解其中常见的一些函数及其用法。我们来详细了解一下吧。 字符串的创建 字符串可以通过两种方式创建,分别是双引号和单引号。 var str1 = "JavaScript"; // 使用双引号创建字符串 var str2 = ‘Jav…

    JavaScript 2023年5月19日
    00
  • JS仿JQuery选择器功能

    下面是JS仿JQuery选择器功能的完整攻略,包含如何实现选择器、示例说明以及注意事项等。 选择器实现原理 实现JS仿JQuery选择器功能的核心在于通过遍历DOM树,找到与选择器匹配的元素。以下是具体实现方法: 解析选择器字符串,获取选择器匹配的元素类型和其他属性,如类名、ID等。 遍历DOM树,从根节点开始,递归查找所有节点,将匹配选项和节点做比对。 检…

    JavaScript 2023年6月10日
    00
  • Javascript验证Visa和MasterCard信用卡号的方法

    验证信用卡号的一种常用方法是通过Luhn算法,该算法有一个基本的规则:把信用卡号从右往左依次编号为0到n,其中最右边一位编号为0,然后对于每个奇数编号的数字乘以二,如果乘以二后的结果大于9,则将结果的各位数字相加,得到一个两位数的数字。 接着,将所有乘以二的数字和除了乘以二的数字的和相加,如果得到的和可以被10整除,则该信用卡号为合法的信用卡号。以下是一个检…

    JavaScript 2023年6月10日
    00
  • JS写XSS cookie stealer来窃取密码的步骤详解

    对于网站作者来说,XSS攻击是一项常见的安全威胁。恶意攻击者可以在网站上注入恶意代码,窃取用户的敏感信息,例如cookie、密码等。下面是一个XSS攻击的示例:使用JavaScript编写一个cookie stealer,当用户访问页面时,将用户的cookie信息发送到黑客的服务器上。下面是攻击的具体步骤: 定义cookie stealer <scri…

    JavaScript 2023年6月11日
    00
  • JS Common 2 之比较常用到的函数

    JS Common 2 之比较常用到的函数 在JavaScript中,有一些函数几乎在每个项目中都会用到,这些函数涵盖了数组、字符串等数据类型的处理,本文将对这些函数进行详细讲解。 Array.prototype.map() 定义 map()方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。 语法 array.map(callb…

    JavaScript 2023年6月10日
    00
  • JavaScript将一个数组插入到另一个数组的方法

    将一个数组插入到另一个数组可以通过以下两种方法实现: 方法一:使用spread operator(展开操作符) 展开操作符可以将一个数组展开成其包含的所有元素,然后将这些元素插入到另一个数组中。下面是这种方法的示例代码: const arr1 = [1, 2, 3]; const arr2 = […arr1, 4, 5, 6]; console.log(…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部