js无痛刷新Token的实现

当我们使用前后端分离的架构时,前端需要向后端服务器发送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判断鼠标位置是否在某个div中的方法

    要判断鼠标位置是否在某个div中,可以通过以下步骤实现。 第一步:获取鼠标的位置信息 要判断鼠标位置是否在某个div中,首先需要获取鼠标在页面中的位置信息。可以通过以下代码来获取: document.addEventListener(‘mousemove’, function(e) { var x = e.clientX; var y = e.clientY…

    JavaScript 2023年6月11日
    00
  • event.X和event.clientX的区别分析

    那么让我们来详细分析一下“event.X和event.clientX的区别”。 1. 事件对象(event)简介 在JavaScript中,与事件相关的数据都被封装在一个事件对象中,该对象用来携带事件发生时的一些信息,比如事件类型、目标元素、鼠标坐标、键盘按键等。 2. event.X和event.clientX的区别 event.X表示鼠标相对于当前元素的…

    JavaScript 2023年6月11日
    00
  • 九个超级好用的Javascript技巧

    九个超级好用的Javascript技巧 Javascript是一门非常强大的语言,但是也有它的一些不足之处。在长时间的开发过程中,我们掌握了一些技巧,能够让我们更好地利用这门语言。以下是九个超级好用的Javascript技巧,让你的代码变得更精简、易读、高效。 把布尔值用!!转化 在Javascript中,我们可以通过使用两个非符号将任何值转化为布尔值。例如…

    JavaScript 2023年6月10日
    00
  • 详解JavaScript对Date对象的操作问题(生成一个倒数7天的数组)

    生成一个倒数7天的数组,可以通过JavaScript中的Date对象来实现。 了解Date对象以及getDate、setDate方法 Date对象是JavaScript中处理日期和时间的核心对象。我们可以利用它来获取当前日期和时间,以及进行各种日期和时间的计算和操作。 Date对象提供了许多方法来获取和设置日期的各个部分。其中,getDate和setDate…

    JavaScript 2023年6月10日
    00
  • 在JavaScript中操作时间之getUTCDate()方法的使用

    当我们在JavaScript中需要操作时间时,getUTCDate()是一个非常实用的方法,它可以获取当前时间基于协调世界时(UTC)的日期中的天数,即1到31之间的整数值。 方法语法 getUTCDate()方法的语法如下: dateObject.getUTCDate() 其中,dateObject表示需要获取日期的Date对象。 方法返回值 getUTC…

    JavaScript 2023年5月27日
    00
  • 微信小程序-小说阅读小程序实例(demo)

    首先,介绍一下这个小程序的功能:小说阅读,用户可以在小程序中阅读小说并添加收藏。下面,给出完整攻略: 1. 确定需求 在开发小程序前,首先需要明确需求,包括用户需要什么功能、界面设计等。在这个小程序中,用户需要一个可以浏览小说和添加收藏的界面。 2. 设计界面 根据需求,设计小程序的界面,包括首页、分类界面、小说详情界面等。 在首页中,用户可以浏览最新的小说…

    JavaScript 2023年6月11日
    00
  • javascript定时器取消定时器及优化方法

    JavaScript定时器 在JavaScript中,我们可以通过setTimeout和setInterval两个方法来实现定时器功能。它们的用法都很类似,但是它们的工作方式有一些不同。 setTimeout setTimeout方法会在指定的时间后执行一次函数。它的基本语法如下: setTimeout(function, delay); 其中,functi…

    JavaScript 2023年6月11日
    00
  • Javascript 面向对象之重载

    Javascript 面向对象之重载 什么是重载 重载(Overloading)指的是一个类中多个方法的名称相同,但是参数列表不同(参数类型、参数个数、参数顺序),这样的方法称为重载方法。在使用时,编译器会根据参数数量、类型和顺序来决定调用哪个方法。 然而在 Javascript 中,由于其灵活的语言特性,本身不支持函数的重载。 如何实现重载 通过 argu…

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