token无感刷新

token无感刷新+长token过期处理+当短token过期之后,需要刷新token,但是进来了很多请求,不需要每个请求都去刷新token处理
所用技术栈:Vue3+TS+Vite+arco-design
1.模拟页面,进行登录和数据请求
<template>
  <div class="refresh">
      <a-button type="outline" status="success" @click="toLogin">登录</a-button>
      <a-button type="outline" status="warning" @click="getInfo">请求受保护的接口</a-button>
  </div>
</template>

<script setup lang="ts">
import { login, reqProtected } from "@/API/getData.js";
const toLogin = async () => {
  const res =  await login() 
}

const getInfo = async () => {
  const res = await reqProtected()
}
</script>
<style scoped lang="less">
.refresh{
  margin-top: 20px;
  display: flex;
  .arco-btn{
    margin-right: 20px;
  }
}
</style>
2.token储存方法封装
const TOKEN_KEY = "TOKEN";
const REFRESH_TOKEN_KEY = "REFRESH_TOKEN";

const getToken = () => {
  return localStorage.getItem(TOKEN_KEY);
};

const setToken = (token) => {
  return localStorage.setItem(TOKEN_KEY, token);
};

const getRefreshToken = () => {
  return localStorage.getItem(REFRESH_TOKEN_KEY);
};

const setRefreshToken = (token) => {
  localStorage.setItem(REFRESH_TOKEN_KEY, token);
};

export {
  getToken,
  setToken,
  getRefreshToken,
  setRefreshToken
}

3.接口封装:request

import axios from "axios";
import { getToken, setToken, setRefreshToken } from "@/utils/token.js";
import { refreshToken, isRefreshRequest } from "./getData.js";
import router from "@/router";
import { Message } from "@arco-design/web-vue";

const baseURL = "http://localhost:9527";

const instance = axios.create({
  // 基础地址
  baseURL,
  // 默认超时的时间
  timeout: 5000,
});

// 请求拦截
instance.interceptors.request.use(
  (config) => {
    // 拿到请求头
    return config;
  },
  (err) => {
    // 打印错误值
    return Promise.reject(err);
  }
);

// 响应拦截
instance.interceptors.response.use(async (res) => {
  // 如果有token 存token
  if (res.headers.authorization) {
    const token = res.headers.authorization.replace("Bearer ", "");
    setToken(token);
    instance.defaults.headers.Authorization = `Bearer ${token}`;
  }
  // 如果有刷新token,存刷新token
  if (res.headers.refreshtoken) {
    const refreshtoken = res.headers.refreshtoken.replace("Bearer ", "");
    setRefreshToken(refreshtoken);
  }
  console.log(res.data.data);
  if (res.data.code === 401 && !isRefreshRequest(res.config)) {
    // 等待token刷新成功
    const isSuccess = await refreshToken();
    // 当长token过期了,需要判断是否获取到了token的信息
    if (isSuccess) {
      // 获取新的token
      res.config.headers.Authorization = `Bearer ${getToken()}`;
      // 获取请求配置,再次请求数据
      const resp = await instance.request(res.config);
      return resp;
    } else {
      Message.warning({
        content: "Token认证过期,请重新登录",
      });
      router.push({
        name: "home",
      });
    }
  }
  return res.data;
});

// 整体导出
export default instance;

4.请求接口封装

import request from "./request.js";
import { getRefreshToken } from "../utils/token.js";
// 登录获取token
export const login = () => request.post("/login");

// 获取需要token认证的接口
export const reqProtected = () => request.post("/protected");

// 假如token过期了,然后需要再次刷新token,但是这个时候同时进来了多个请求,其实只需要刷新一次token
let promise = null;
// 刷新token 这里需要等待刷新token完成,否则会执行多次
export const refreshToken = () => {
  if (promise) {
    return promise;
  }
  promise = new Promise(async (resolve) => {
    const res = await request.get("/refresh_token", {
      headers: {
        Authorization: `Bearer ${getRefreshToken()}`,
      },
      __isRefreshToken: true, //增加刷新token的辨识
    });
    resolve(res.code === 0)
  });
  console.log(promise,'  console.log(promise);');
  // 完成刷新token之后,需要把promise置空,因为后续还会进行判断执行
  promise.finally(() => {
    promise = null;
  });
  // 这里为什么要return promise ,因为你再外部调用的时候,需要去执行他:await refreshToken()
  // 然后才会执行到调用接口,并返回resolve结果
  return promise;
};

// 判断是否为刷新token
export const isRefreshRequest = (config) => {
  return !!config.__isRefreshToken;
};
可以仔细观看代码,详细解释都在其中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/598610.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

有没有电脑桌面监控软件|十大电脑屏幕监控软件超全盘点!

当然&#xff0c;目前市场上有许多电脑桌面监控软件可供选择&#xff0c;它们各有特色&#xff0c;旨在满足不同企业和个人对于远程监控、安全管理、提高工作效率等方面的需求。以下是根据近期资料整理的十大电脑屏幕监控软件盘点&#xff0c;包括它们的一些特点和优势&#xf…

Web3:下一代互联网的科技进化

随着科技的不断演进&#xff0c;互联网已经成为了我们生活中不可或缺的一部分。而在Web3时代&#xff0c;我们将会见证互联网进化的下一个阶段。本文将探讨Web3作为下一代互联网的科技进化&#xff0c;以及它所带来的重要变革和影响。 传统互联网的局限性 传统互联网存在诸多…

如何从零开始学习数据结构?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「数据结构的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;数据结构 算法&#xff1d;程…

MySQL日志机制【undo log、redo log、binlog 】

前言 SQL执行流程图文分析&#xff1a;从连接到执行的全貌_一条 sql 执行的全流程?-CSDN博客文章浏览阅读1.1k次&#xff0c;点赞20次&#xff0c;收藏12次。本文探讨 MySQL 执行一条 SQL 查询语句的详细流程&#xff0c;从连接器开始&#xff0c;逐步介绍了查询缓存、解析 S…

xmind的13个快捷方式

1.新建导图 CtrlshiftN 2.编辑文字 空格键 3.插入图片 Ctrli 4. 插入主题 Enter键 5. 插入主题之前 ShiftEnter键 6. 插入子主题 Tab键 7. 放大导图 “Ctrl”“” 8. 缩小导图 “Ctrl”“-” 9. 复制 CtrlInsert 10. 粘贴 Shift Insert 11. 剪切 ShiftDelete 12. 截图 F7 13. 保…

【Pytorch】5.DataLoder的使用

什么是DataLoader 个人理解是&#xff0c;如果Dataset的所有数据相当于一副扑克牌&#xff0c;DataLoader就相当于从扑克牌中抽取几张&#xff0c;我们可以规定一次抽取的张数&#xff0c;或者以什么规则进行抽取 DataLoader的使用 查阅官网的文档&#xff0c;主要有这几个参数…

Unity Shader中获取像素点深度信息

1.顶点着色器中对深度进行计算 v2f vert(appdata v) {v2f o;o.pos UnityObjectToClipPos(v.vertex);o.uv TRANSFORM_TEX(v.uv, _MainTex);o.depth (o.pos.z / o.pos.w 1.0) * 0.5; // Normalize depth to [0, 1]return o; }但是达不到预期&#xff0c;最后返回的值一直大于…

SpringMVC响应数据

三、SpringMVC响应数据 3.1 handler方法分析 理解handler方法的作用和组成&#xff1a; /*** TODO: 一个controller的方法是控制层的一个处理器,我们称为handler* TODO: handler需要使用RequestMapping/GetMapping系列,声明路径,在HandlerMapping中注册,供DS查找!* TODO: ha…

数据挖掘实战-基于深度学习RNN+CNN的能源价格预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

java JMH 学习

JMH 是什么&#xff1f; JMH&#xff08;Java Microbenchmark Harness&#xff09;是一款专用于代码微基准测试的工具集&#xff0c;其主要聚焦于方法层面的基准测试&#xff0c;精度可达纳秒级别。此工具由 Oracle 内部负责实现 JIT 的杰出人士编写&#xff0c;他们对 JIT 及…

翻译《The Old New Thing》 - What is the deal with the ES_OEMCONVERT flag?

What is the deal with the ES_OEMCONVERT flag? - The Old New Thinghttps://devblogs.microsoft.com/oldnewthing/20050719-12/?p34893 Raymond Chen 在 2005年07月19日 ES_OEMCONVERT 标志是怎么回事&#xff1f; 简要 文章讨论了 ES_OEMCONVERT 编辑控件风格的起源和用途…

java将图片转为pdf

效果图 直接上代码 1.引入jar <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.24</version></dependency> 2.测试类 package pers.wwz.study.img2pdf20240507;import org.a…

MetaCRM upload 任意文件上传漏洞

文章目录 漏洞描述漏洞原理漏洞复现修复建议 漏洞描述 北京美特软件技术有限公司&#xff08;以下简称“美特软件”&#xff09;是一家专业的客户关系管理软件提供商。 美特软件MetaCrm存在文件上传漏洞&#xff0c;攻击者可利用该漏洞上传任意恶意文件。 漏洞原理 在系统u…

什么牌子的骨传导耳机质量好?五大宝藏热门机型测评对比!

我作为一名音乐发烧友&#xff0c;对各类耳机产品都有深入的了解&#xff0c;最近也经常被人问及骨传导耳机哪个牌子好。通过交流&#xff0c;我发现很多人在选择骨传导耳机的时候&#xff0c;都有出现踩坑的情况&#xff0c;这也难怪&#xff0c;随着骨传导耳机热度逐渐增加&a…

护眼灯排名前十的品牌有哪些?护眼灯品牌排行前十名推荐

近视在儿童中愈发普遍&#xff0c;许多家长开始认识到&#xff0c;除了学业成绩之外&#xff0c;孩子的视力健康同样重要。毕竟&#xff0c;学业的落后可以逐渐弥补&#xff0c;而一旦孩子近视&#xff0c;眼镜便可能成为长期伴随。因此&#xff0c;专业的护眼台灯对于每个家庭…

220V转18V500mA非隔离恒压WT5113

220V转18V500mA非隔离恒压WT5113 亲爱的朋友们&#xff0c;你们是否在为如何提高电源方案而烦恼呢&#xff1f;今天我给大家带来了一款芯片&#xff0c;WT5113宽输出范围非隔离交直流转换芯片&#xff0c;它可是电源方案中的得力助手哦&#xff01; 这款芯片拥有220V降12V、2…

docker-compose 运行jenkins 并一键发布springboot项目

文档时间&#xff1a; 2024-05-07 jenkins一键发布原理个人理解&#xff1a; 本质就是通过jenkins 配置git地址&#xff0c;然后通过地址拉取代码到服务器上&#xff0c; 然后jenkins 再通过maven把拉取下来的进行打包。 再通过jenkins 配置的shell命令&#xff0c;在服务…

ubuntu20.04搭建Fabric教程

本章节环境配置 ubuntu: 20.04 go&#xff1a;1.16.3 docker: 20.10.6 docker-compose: 1.27.2 fabric&#xff1a;2.2.0 fabric-ca: 1.4.9 一 搭建通道 新建工作目录 mkdir fabric && cd fabric配置go代理 go env -w GO111MODULEon ​ #更新下载包的镜像 go env …

Python中GDAL批量将多个遥感影像各波段数值缩小10000倍的方法

本文介绍基于Python中的gdal模块&#xff0c;批量读取大量多波段遥感影像文件&#xff0c;分别对各波段数据加以数值处理&#xff0c;并将所得处理后数据保存为新的遥感影像文件的方法。 首先&#xff0c;看一下本文的具体需求。我们现有一个文件夹&#xff0c;其中含有大量.ti…

数据结构:环形链表的实战指南

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;http://t.csdnimg.cn/oHJAK&#xff08;数据结构与算法&#xff09; 小新的主页&#xff1a;编程版小新-CSDN博客 …
最新文章