欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > 前端判断Token是否失效,并更新Token

前端判断Token是否失效,并更新Token

2024/12/22 1:02:51 来源:https://blog.csdn.net/qq_38998250/article/details/144367386  浏览:    关键词:前端判断Token是否失效,并更新Token

用户登录系统后,都会赋予用户一个Token,这样用户在操作系统时,只需要将Token传给后端就可以了,无需对用户重复进行身份验证

既然Token如此重要,为了安全起见,Token的有效期也不会设置过长。

那么将由前后端谁来判断Token是否失效呢?只能说各有优劣

前后端优缺点

// 简单说一下主要几点
// 前端
优点:体验好,减少服务端的负担;
缺点:不安全,依赖本地时间,可以被伪造或篡改,容易被攻击者利用;
// 后端
优点:安全性高,只有服务端知道Token是否失效,可以防止客户端伪造或篡改信息;还能简化前端处理逻辑;
缺点:增加了服务端的负担,每次请求都需要进行验证,可能对性能有影响

前端处理逻辑

本期主要重点讲 前端是如何处理Token失效逻辑的。

为了不频繁更新Token,前端应该设置一个更新时间失效时间

分析

场景和逻辑很简单:

  • 1、用户登录系统,后端返回前端Token有效期时间(3天);
    那么更新时间设为2天半后失效时间设为3天后

  • 2、用户在3天后访问系统判断其Token失效,去往登录页重新登录

  • 3、用户在2天半前访问系统,则不需要特殊处理,使用本地储存的Token就可以了;
    更新时间不变,但是失效时间应该改为 当前时间 + 3天

  • 4、用户在2天半 — 3天这个时间段访问系统,则需要请求后端返回新Token
    更新时间和失效时间 则需要执行步骤1的逻辑

代码逻辑

主要有两处地方需要添加逻辑:
1、项目中 pinia/vuex 状态管理库,需要对时间进行储存和判断
2、接口请求时,公共api层是否需要更新token

pinia状态管理

// 不同项目,不同开发习惯,目录结构都不一样; 这里主要凸显出这是一个状态管理库文件
// store/modules/global.js 
// 使用pinia储存: 更新时间、失效时间、Tokenimport { defineStore } from 'pinia'export const glStore = defineStore('glStore', {persist: {storage: {setItem(key, value) {uni.setStorageSync(key, value)},getItem(key) {return uni.getStorageSync(key)}}},state: () => {return {token: '',userInfo: {},// 失效时间expirationTime: 0,// 更新时间updateTime: 0}},actions: {setToken(value) {this.token = value},setUserInfo(userInfo) {if (userInfo.token) {this.setToken(userInfo.token)delete userInfo.token}this.userInfo = userInfo},getDate() {// 3天const threshold = 3 * 24 * 60 * 60 * 1000// 失效前半天const interval = 12 * 60 * 60 * 1000const now = new Date()// 当前时间const currentTime = now.getTime()// 失效时间const failure = currentTime + threshold// 更新时间const update = threshold + currentTime - intervalconsole.log(update, this.formatTime(update), '--------2天半后')console.log(failure, this.formatTime(failure), '--------3天后')console.log(currentTime, this.formatTime(currentTime), '--------当前时间')// 1:更新Token;// 2:更新失效期;// 3:Token失效了;// 4:未知if (!this.expirationTime) {this.expirationTime = failurethis.updateTime = updatereturn '1'} else {// 当前时间 小于 更新时间if (currentTime < this.updateTime) {// 更新失效时间为  最新当前时间的3天后this.expirationTime = failurereturn '2'} else if (currentTime > this.updateTime && currentTime > this.expirationTime) {// 更新Token--- 重复最开始操作this.expirationTime = failurethis.updateTime = updatereturn '1'} else if (currentTime > this.updateTime) {// 当前时间 大于  失效时间 == Token失效return '3'} else {return '4'}}},formatTime(timestamp) {const date = new Date(timestamp)const formattedDate = date.toLocaleString()return formattedDate}}
})

API 请求

// 接口域名
import { host } from '$api/baseUrl.js'
// 设置请求头
import { setHeader } from './sign'
// pinia
import { glStore } from '@/store/modules/global.js'
// 请求后拦截
function responseFn(res, resolve, reject) {if (res.code === 0) {resolve(res)} else if (res.code === 401300) {// token过期uni.showModal({// 弹出提示框title: '重新登录',content: '登录过期,请重新登录!',success(res) {if (res.confirm) {// 用户点击确定按钮uni.navigateTo({ url: '/pages/login/index' })}},fail(e) {console.log(e, '确认取消弹出未弹出')}})} else {uni.showToast({title: res.msg,icon: 'none',duration: 1000})reject(res)}
}async function fetch(url, data = {}, method = 'POST') {const store = glStore()let type = store.getDate()// 不需要Token的接口let urls = ['xxx/code', 'xxx/login']if (type === '1' && !urls.includes(url)) {let res = await $ajax('url---token', data, method)store.setUserInfo(res.data)}return $ajax(url, data, method)
}async function $ajax(url, data = {}, method = 'POST') {return new Promise((resolve, reject) => {uni.request({url: host + url,header: setHeader({url,method,data: data || {}}),data,method,success(res) {responseFn(res.data, resolve, reject)},fail: function(err) {uni.hideLoading()reject(err)}})})
}const $get = (url = '', data = {}) => {return fetch(url,data,'get')
}const $post = (url = '', data = {}) => {return fetch(url,data)
}const $delete = (url = '', data = {}) => {return fetch(url,data,'delete')
}const $put = (url = '', data = {}) => {return fetch(url,data,'put')
}export { $get, $post, $delete, $put }

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com