关于公司小程序项目在登录流程获取token并全局使用的梳理(学习篇)

news/2024/9/28 21:11:04/

首先打开公司的项目,由于公司前端使用的是tarojs+vue+babel,因此需要先安装tarojs-cli并运行编译

之后研究前端前辈们的代码,来学习一下前端怎么获取token并全局使用

首先思路搞清楚,token是通过调取后端的登录接口,并在后端成功返回后拿到并全局使用的,基于这个思路,我们先看看调用login函数和定义login函数的地方

调用login函数位于src\pages\common\login\index.vue的:

// 调用 useService('Auth')获取一个与认证相关的服务对象,然后调用其 login 方法进行登录操作,
// 传入包含 code、encryptedData 和 iv 的对象作为登录参数,并等待这个异步操作完成
if (await useService('Auth').login({code: wxCode.value,encryptedData: detail.encryptedData,iv: detail.iv
})) {// 如果登录成功且 eventId.value 有值,则触发名为 eventId.value(登录成功) 的事件eventId.value && eventCenter.trigger(eventId.value);// 如果登录成功且 eventId.value 没有值,则执行返回上一页的操作!eventId.value && useNavigateBack();
} else {// 如果登录失败,执行返回上一页的操作useNavigateBack();
}

这里用到了useService('Auth'),而useService函数位于src\service\useService.ts的:

export default function useService(serviceName: string) {//获取了被加载文件的默认导出(假设 serviceName 指向的文件中有一个默认导出的类)。const ctor = require('./' + serviceName).default//返回了一个新的实例化对象,这样调用方就可以使用这个对象上的方法,比如 .login 方法。return new ctor()
}/**
useService('Auth'):当传入 'Auth' 作为参数时,
useService函数会尝试加载 ./Auth,也就是相对路径下名为 Auth.ts 的文件。
由于有 src/service/Auth.ts 文件存在,
并且假设这个文件在当前上下文的相对路径符合 useService 的加载规则,
那么这个调用就会加载 src/service/Auth.ts 文件。
**/

由此可知useService('Auth').login是通过useService函数导出了Auth类对象,并调用其login函数。

我们找到位于src\service\Auth.ts的login函数:

async login(args: AuthPhoneNumberProps) {// 移除名为 "USER_LOGOUT" 的存储项this.useStorage.removeStorage("USER_LOGOUT");// 创建一个加载提示,显示标题为"正在登录...",并在变量 hideLoading 中保存用于关闭提示的函数const hideLoading = useLoading({ title: '正在登录...' });// 调用 this.model.login 方法进行登录操作,将传入的参数 args 展开传递,并解构赋值结果为 [error, response]const [error, { data }] = await this.model.login({...args });// 如果有错误发生if (error) {// 触发名为 "refreshWxCode" 的事件eventCenter.trigger('refreshWxCode');// 关闭加载提示hideLoading();// 直接返回,不继续执行后续代码return;}// 将登录成功后获取的数据提交到 store 的 login mutation 中store.commit('login', data);// 调用名为 "Classes" 的服务获取活跃班级信息await useService('Classes').fetchActiveClassInfo();// 关闭加载提示hideLoading();// 返回 true,表示登录成功并执行了后续操作return true;
}

发现该函数调用store.commit('login', data),这里的data是从后端获取的登录响应数据。

当store.commit('login', data)被调用时,实际上会执行login mutation 函数。

而这个login mutation 函数则是在src\store\index.ts中mutations里定义的:

// 定义 Vuex 的 mutations 对象,用于更改状态
mutations: {// init 方法,用于初始化状态init(state) {// 从本地存储中获取用户信息并设置到 Vuex 的 state 中的 user 属性state.user = useStorage().getStorage(STORE_USER);// 从本地存储中获取 token 并设置到 Vuex 的 state 中的 token 属性state.token = useStorage().getStorage(STORE_TOKEN);},// login 方法,用于处理登录成功后的状态更新login(state, obj) {// 设置登录状态为 truestate.isLoginState = true;// 将登录后的 accessToken 存储到本地存储中,并以 STORE_TOKEN 为键useStorage().setStorage(STORE_TOKEN, obj.accessToken);// 将登录后的用户信息存储到本地存储中,并以 STORE_USER 为键useStorage().setStorage(STORE_USER, obj.user);// 计算并设置登录过期时间到本地存储中,以 STORE_EXPIRATION 为键useStorage().setStorage(STORE_EXPIRATION, new Date().getTime() + (LOGIN_TIME || 720) * 60 * 1000);// 更新 Vuex 的 state 中的 user 属性为登录后的用户信息对象的扩展形式state.user = {...obj.user };// 更新 Vuex 的 state 中的 token 属性为登录后的 accessTokenstate.token = obj.accessToken;},
};

在这里可以看到,state.token在init mutation被赋值一次,在login mutation 函数中被obj.accessToken赋值一次。

之后来到src\request\http.ts,查看配置 HTTP 请求拦截器,因为在发送请求之前,拦截器会对请求进行一些预处理操作(比如说把token传入请求头)

http.interceptors.request = (request) => {// 如果 store 的 getters 中有 tokenif (store.getters.token) {// 将环境变量 TOKEN_NAME 作为键名,把 store 中的 token 值设置到请求头中request.header[process.env.TOKEN_NAME as string] = store.getters.token;}// 设置请求头的 Content-Type 为 application/jsonrequest.header['content-type'] = 'application/json';// 返回修改后的请求配置对象return request;
};

这里用到了store.getters.token,但是赋值的时候明明是赋值给state.token,这两者之间有什么关系呢?

这里查到了他们的关系,state是原始状态数据的存储,而store.getters是基于state计算得到的派生状态,它们共同构成了 Vuex 状态管理中的重要组成部分,为应用的组件提供了可预测、可维护的数据访问方式。而如果没有明确为token定义一个 getter,那么store.getters.token不会自动等同于state.token。所以基于这个角度考虑,我们需要去查token是怎么定义 getter的

回到src\store\index.ts中,发现token的 getter定义代码

getters: {token: (state) => {// 从本地存储中获取存储的过期时间,并转换为浮点数const expirationTime = parseFloat(useStorage().getStorage(STORE_EXPIRATION));// 如果过期时间存在且当前时间小于过期时间if (expirationTime && new Date().getTime() < expirationTime) {// 返回 state 中的 tokenreturn state.token;}// 如果不满足上述条件,返回空字符串return "";},
},

这样就可以在 HTTP 请求拦截器中使用store.getters.token,从而实现每次请求,都来实时判断token是否过期,获取token来全局控制用户登录情况了


http://www.ppmy.cn/news/1530801.html

相关文章

接口自动化

一、数据库及数据库操作概念 1.数据库概述 概念 存数据的仓库,程序中数据的载体 数据库和变量都可以存储数据,二者有什么区别? 持久性不同:数据库可以持久性存储数据(将数据写入磁盘文件),而变量不能(运行在内存中) 分类: 关系型数据库(MySQL、Oracle、SQLite):安全 由行和…

前端sm2国密加密时注意

如下方法&#xff1a; export function encrypt(str) {const sm2 require("sm-crypto").sm2;const cipherMode 1; // 1 - C1C3C2&#xff0c;0 - C1C2C3&#xff0c;默认为1//自定义密钥let publicKey "xxxxxxxx";//此处加密let a sm2.doEncrypt(str,…

OpenCV特征检测(8)检测图像中圆形的函数HoughCircles()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在灰度图像中使用霍夫变换查找圆形。 该函数使用霍夫变换的一种修改版本在灰度图像中查找圆形。 例子&#xff1a; #include <opencv2/imgp…

Mac优化清理工具CleanMyMac X 4.15.6 for mac中文版

CleanMyMac X 4.15.6 for mac中文版下载是一款功能更加强大的系统优化清理工具&#xff0c;软件只需两个简单步骤就可以把系统里那些乱七八糟的无用文件统统清理掉&#xff0c;节省宝贵的磁盘空间。CleanMyMac X 4.15.6 for mac 软件与最新macOS系统更加兼容&#xff0c;流畅地…

零成本玩转企业微信!2024年邮箱功能新升级,速来get√

在这个网络时代&#xff0c;公司聊天和管理得快不快&#xff0c;对公司能不能赢很关键。企业微信是腾讯给公司做的聊天和办公工具&#xff0c;因为功能多、用着方便&#xff0c;很多公司都喜欢用。不过&#xff0c;新用企业微信的公司最想知道的是&#xff1a;用这个要不要花钱…

Spring Boot框架:蜗牛兼职网实现

第3章 系统分析 3.1 需求分析 蜗牛兼职网主要是为了提高工作人员的工作效率和更方便快捷的满足用户和企业&#xff0c;更好存储所有数据信息及快速方便的检索功能&#xff0c;对系统的各个模块是通过许多今天的发达系统做出合理的分析来确定考虑用户和企业的可操作性&#xff0…

Java律师法律咨询小程序

技术&#xff1a;Java、Springboot、mybatis、Vue、Mysql、微信小程序 1.代码干净整洁&#xff0c;可以快速二次开发和添加新功能 2.亮点可以添加AI法律咨询作为 创新点 系统分&#xff1a;用户小程序端&#xff0c;律师web端和管理员端 用户可以在小程序端登录系统进入首…

如何进行Ubuntu磁盘空间深度清理?

近期使用AutoDL算力云&#xff0c;发现系统盘只有30G&#xff0c;数据盘只有50G&#xff0c;跑一个稍微大一点的模型&#xff0c;马上空间就拉爆了&#xff0c;现在做一个磁盘深度清理操作&#xff0c;看看效果。 清理前磁盘占用如下&#xff1a; 在 Ubuntu 系统中进行磁盘深度…