当前位置:首页 » 《资源分享》 » 正文

前端Token管理(获取、过期处理、异常处理及优化)_前端登录及登录过期

22 人参与  2024年09月23日 18:40  分类 : 《资源分享》  评论

点击全文阅读


img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

* 登录页面使用(伪代码)

import Vue from ‘vue’
import { login } from ‘@/services/user’
export default Vue.extend({
name: ‘LoginIndex’,
data() {
return {
formData: {
phone: ‘18201288771’,
password: ‘111111’
}
}
},
methods: {
async submit() {
try {
const { data } = await login(this.formData)
// 处理请求结果
if (data.state !== 1) {
this.KaTeX parse error: Expected 'EOF', got '}' at position 37: …ssage) }̲ else { …store.commit(‘setUser’, data.content)
this.$message.success(‘登录成功’)
}
} catch (error) {}
this.isLoading = false
}
}
})

* axios请求拦截器

// 请求拦截器,每一个请求都会经过此拦截器。
request.interceptors.request.use((config) => {
// 在请求的header中设置token
config.headers.Authorization = store.state?.user?.access_token
return config
}, (error) => {
return Promise.reject(error)
})

![](https://img-blog.csdnimg.cn/img_convert/de6d3f4387011d6d6be5b32007941a96.png)#### 优化——授权过期登录重新返回页面![在这里插入图片描述](https://img-blog.csdnimg.cn/20210525173940921.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyOTMwODYz,size_16,color_FFFFFF,t_70#pic_center)##### request.js中

// 跳转至首页封装
const redirectLogin = () => {
router.push({
name: ‘login’,
query: {
// 通过参数传 登录成功后的跳转地址
redirect: router.currentRoute.fullPath
}
})
}

##### 登录页面

methods: {
// 登录请求方法
async submit() {
try {
const { data } = await login(this.formData)
// 处理请求结果
if (data.state !== 1) {
//… 登录失败处理逻辑
} else {
//… 登录成功处理逻辑
// 登录成功后进行路由跳转
this. r o u t e r . p u s h ( ( t h i s . router.push((this. router.push((this.route.query.redirect as string) || ‘/’)
}
} catch (error) {}
}
}

#### 优化——页面刷新Token丢失

export default new Vuex.Store({
state: {
// 初始化时从本地存储中获取
user: JSON.parse(window.localStorage.getItem(‘user’) || ‘null’)
},
mutations: {
//设置用户登录信息
setUser(state, payload) {
//因目前后端返回的是json字符串,所以我转义了一下
payload = JSON.parse(payload)
//如果pyload中没有过期时间并且存在过期时间长度
if (!payload.expires_at && payload.expires_in) {
//设置过期时间
payload.expires_at = new Date().getTime() + payload.expires_in * 1000
}
//赋值
state.user = payload
//每次设置用户登录信息都存储值本地存储
window.localStorage.setItem(‘user’, JSON.stringify(payload))
}
},
actions: {
},
modules: {
}
})

### 过期维护过期维护存前端存在两种方式* 在请求发起前拦截每个请求,判断token的有效时间是否已经过期。若已过期,则将请求挂起,先刷新token后在继续请求。+ 优点:请求前拦截,节省请求及流量+ 缺点:需要后端额外提供过期时间字段,若本地时间与服务器时间不一致可能存在拦截失败。* 不在请求前拦截,而是拦截返回后的数据。先放弃请求,接口返回过期后,先刷新token,在进行一次重试。+ 优点:不需要额外的token过期字段及判断时间+ 缺点:会消耗多一次请求,耗流量#### 请求发起前拦截![](https://img-blog.csdnimg.cn/img_convert/360aadadceef2e95d03a3986feb10898.png)

// 跳转首页逻辑
const redirectLogin = () => {
router.push({
name: ‘login’,
query: {
redirect: router.currentRoute.fullPath
}
})
}

// 刷新token后的任务队列
let refreshTokenArray = []

/**
* 刷新token,重新请求
*/
const refreshTokenFn = async () => {
// 判断是否有刷新token
const refreshToken = store.state?.user?.refresh_token || ‘’
// 如果刷新token存在
if (refreshToken) {
// 使用重新创建的axios请求,防止递归调用
const { data } = await axios.create()({
method: ‘POST’,
url: ‘/front/user/refresh_token’,
data: qs.stringify({
refreshtoken: refreshToken
})
})
//如果获取token失败 抛出异常
if (!data.content) throw new Error(‘refreshToken is faild’)
// 重新设置token
store.commit(‘setUser’, data.content)
return true
}
throw new Error(‘refreshToken not find’)
}

// 请求拦截器
request.interceptors.request.use(async (config: Config) => {
// 获取用户登录信息
const user = store.state?.user
// 判断access_token 是否过期且接口是否需要token
if (config.isAuthToken && user.expires_at < new Date().getTime()) {
// 是否正在执行刷新token
if (!refreshTokenLoding) {
try {
//刷新token锁为true
refreshTokenLoding = true
await refreshTokenFn()
// 执行获取token后的任务队列
refreshTokenArray.forEach(item => item())
//清空任务队列
refreshTokenArray = []
return config
} catch (error) {
// 如果刷新失败跳转登录页面
redirectLogin()
} finally {
// 无论成功失败消除
refreshTokenLoding = false
}
} else {
// 如果这正在刷新,返回一个 Promise ,并向刷新token成功后执行队列push 函数.
return new Promise(resolve => {
refreshTokenArray.push(() => {
// 返回config请求对象
resolve(config)
})
})
}
}
return config
})

#### 请求发起后拦截![img](https://img-blog.csdnimg.cn/img_convert/6e0afa2515a202daee9e323075ad0604.png)![img](https://img-blog.csdnimg.cn/img_convert/f9a0c0fa21a9d9dee0e14aad756d1b63.png)**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!****由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新****[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**图片转存中...(img-5NdvB8Ze-1715711482905)]**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!****由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新****[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

点击全文阅读


本文链接:http://zhangshiyu.com/post/163660.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1