首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

业务场景---Token无感刷新

编程知识
2024年07月27日 11:34

业务场景描述

假设用户正在填写一个复杂的表单,由于表单内容繁多,用户花费了很长时间才填完。这时,如果Token已经过期,系统会让用户重新登录,这种体验显然是非常糟糕的。为了避免这种情况,我们需要在Token即将过期或已经过期时,自动刷新Token,而不影响用户正在进行的操作。

技术实现思路

一、准备工作

  1. 前端框架选择:本文以Vue.js为例,结合Vue Router和Axios来实现Token无感刷新机制。
  2. 后端支持:后端需要提供刷新Token的接口,当接收到旧的Token时返回一个新的Token。

二、关键技术点

  1. 拦截请求:使用Axios拦截器来检测每一个请求的状态,如果发现Token过期,则触发刷新Token的逻辑。
  2. 刷新Token:实现一个专门用于刷新Token的方法,该方法会在旧的Token过期时自动调用并更新Token。
  3. 请求队列:在刷新Token期间,暂停其他需要Token的请求,待Token刷新成功后,重新发送这些请求。

三、具体实现步骤

1. 配置Axios拦截器

首先,配置Axios拦截器来检测请求和响应的状态,并在Token过期时触发刷新Token的逻辑。

import axios from 'axios';
import store from './store'; // 假设使用Vuex来管理全局状态
import router from './router';

let isRefreshing = false;
let requests = [];

axios.interceptors.request.use(
  config => {
    const token = store.state.token;
    if (token) {
      config.headers['Authorization'] = 'Bearer ' + token;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

axios.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    const { config, response } = error;
    const originalRequest = config;
    
    if (response && response.status === 401) {
      if (!isRefreshing) {
        isRefreshing = true;
        return refreshToken().then(newToken => {
          store.commit('setToken', newToken);
          originalRequest.headers['Authorization'] = 'Bearer ' + newToken;
          processQueue(null, newToken);
          return axios(originalRequest);
        }).catch(err => {
          processQueue(err, null);
          store.commit('logout');
          router.push('/login');
          return Promise.reject(err);
        }).finally(() => {
          isRefreshing = false;
        });
      } else {
        return new Promise((resolve, reject) => {
          requests.push((token) => {
            originalRequest.headers['Authorization'] = 'Bearer ' + token;
            resolve(axios(originalRequest));
          });
        });
      }
    }
    return Promise.reject(error);
  }
);

function processQueue(error, token = null) {
  requests.forEach(promise => {
    if (error) {
      promise.reject(error);
    } else {
      promise.resolve(token);
    }
  });
  requests = [];
}

 

2. 实现刷新Token的方法

接下来,实现一个用于刷新Token的方法refreshToken。这个方法会调用后端接口来获取新的Token。

function refreshToken() {
  return new Promise((resolve, reject) => {
    axios.post('/auth/refresh', {
      refreshToken: store.state.refreshToken
    }).then(response => {
      if (response.data.success) {
        resolve(response.data.token);
      } else {
        reject(response.data.message);
      }
    }).catch(error => {
      reject(error);
    });
  });
}

 

3. 更新Vuex状态管理

确保在Vuex中有相关的状态和方法来管理Token和用户登录状态。

 

const store = new Vuex.Store({
  state: {
    token: localStorage.getItem('token') || '',
    refreshToken: localStorage.getItem('refreshToken') || '',
    user: {}
  },
  mutations: {
    setToken(state, token) {
      state.token = token;
      localStorage.setItem('token', token);
    },
    setRefreshToken(state, refreshToken) {
      state.refreshToken = refreshToken;
      localStorage.setItem('refreshToken', refreshToken);
    },
    logout(state) {
      state.token = '';
      state.refreshToken = '';
      state.user = {};
      localStorage.removeItem('token');
      localStorage.removeItem('refreshToken');
    }
  }
});

 

4. 处理登录逻辑

确保在用户登录时,正确地存储Token和刷新Token。

function login(credentials) {
  return axios.post('/auth/login', credentials).then(response => {
    store.commit('setToken', response.data.token);
    store.commit('setRefreshToken', response.data.refreshToken);
  });
}

 

总结:当用户在填写复杂表单时,即使Token过期也不会中断他们的操作,从而提供了更好的用户体验。这个机制不仅适用于表单填写,还可以广泛应用于任何需要长时间交互的Web应用场景中。

 

From:https://www.cnblogs.com/zx618/p/18326822
本文地址: http://www.shuzixingkong.net/article/477
0评论
提交 加载更多评论
其他文章 FFmpeg开发笔记(四十一)结合OBS与MediaMTX实现SRT直播推流
​《FFmpeg开发实战:从零基础到短视频上线》一书的“10.2 FFmpeg推流和拉流”提到直播行业存在RTSP和RTMP两种常见的流媒体协议。除此以外,还有于2017年推出的SRT协议,相比常见的RTMP协议,SRT协议具有更低的延迟,并且消除了卡帧、抖动等花屏现象。腾讯视频云已经引入了SRT协
FFmpeg开发笔记(四十一)结合OBS与MediaMTX实现SRT直播推流
OpenAI深夜丢炸弹硬杠谷歌搜索
这几年科技变革太快,AI更是飞速发展,作为一名IT老兵,使用过的搜索引擎也是一换再换。这不,刚消停了一段时间的OpenAI又丢出一个炸弹SearchGPT,直接跟谷歌掀桌子了。
OpenAI深夜丢炸弹硬杠谷歌搜索 OpenAI深夜丢炸弹硬杠谷歌搜索
STM32开发环境配置记录——关于PlatformIO + VSCode + CubeMX的集成环境配置
前言 ​ 为什么配置这样的一个环境呢?鄙人受够了Keil5那个简陋的工作环境了,实在是用不下去,调试上很容易跟CubeMX的代码产生不协调导致调试——发布代码不一致造成的一系列问题。CubeIDE虽说不错,但是它的代码辅助功能和构建系统实在不敢恭维,经常出现Makefile未同步导致符号定义冲突,亦
STM32开发环境配置记录——关于PlatformIO + VSCode + CubeMX的集成环境配置 STM32开发环境配置记录——关于PlatformIO + VSCode + CubeMX的集成环境配置 STM32开发环境配置记录——关于PlatformIO + VSCode + CubeMX的集成环境配置
Django模型中的save方法 精讲
两种方法定义在Django模型中的save方法有不同的参数处理方式。 第一种方法: def save(self, *args, **kwargs): super().save(*args, **kwargs) 特点: 使用*args和**kwargs来捕获所有位置参数和关键字参数。 这样的方法可以灵
不是,大哥,咱这小门小户的,别搞我CDN流量啊
分享是最有效的学习方式。 博客:https://blog.ktdaddy.com/ 最近遇上事儿了,老猫的小小博客网站【程序员老猫的博客】被人盗刷CDN流量了。开始的时候收到了欠费的短信也没有怎么去重视。虽然说费用没有多少,但是也是一个教训。 博客从最初地搭建到现在确实也经过好几年了,天真地以为确实
不是,大哥,咱这小门小户的,别搞我CDN流量啊 不是,大哥,咱这小门小户的,别搞我CDN流量啊 不是,大哥,咱这小门小户的,别搞我CDN流量啊
一款.NET开源、跨平台的DASH/HLS/MSS下载工具
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、跨平台的DASH/HLS/MSS下载工具,并且支持点播和直播(DASH/HLS)的内容下载:N_m3u8DL-RE。 网络流媒体传输协议介绍 DASH DASH是一种基于HTTP的自适应流媒体网络传输协议,它允许流媒体内容以多
一款.NET开源、跨平台的DASH/HLS/MSS下载工具 一款.NET开源、跨平台的DASH/HLS/MSS下载工具 一款.NET开源、跨平台的DASH/HLS/MSS下载工具
《Programming from the Ground Up》阅读笔记:p88-p94
《Programming from the Ground Up》学习第5天,p88-p94总结,总计7页。 一、技术总结 1.touppercase.s #PURPOSE: This program converts an input file #to an output file with all
《Programming from the Ground Up》阅读笔记:p88-p94
C# 通过反射(Reflection)调用不同名泛型方法
概述 由于工作需要,需要通过数据类型和方法名控制方法走向 用到的数据类型有8种(string,Int16,Int32,Int64,Boolean,Byte,Single,Double) 读取的方法(参数一致,但是数据不同的泛型方法,返回值也是泛型)暂时只有11种,但肯定的是,后续一定会增加 原本计划