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

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)**

  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值