vue3 使用pinia存储用户信息、axios拦截哀求添加token、用户权限约束操作方 ...

打印 上一主题 下一主题

主题 1025|帖子 1025|积分 3075

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一、使用pinia

  1. 安装pinia
  2. 安装pinia-plugin-persistedstate
  3. vue根目录创建stores,创建indexjs,内容如下:
复制代码
  1. import { createPinia } from 'pinia'
  2. import persist from 'pinia-plugin-persistedstate'
  3. // app.use(createPinia().use(persist))
  4. const pinia=createPinia()
  5. pinia.use(persist)
  6. export default pinia
  7. export * from './user'
复制代码
  1. stores文件中再创建user.js,完整代码如下:
复制代码
  1. import { ref } from 'vue'
  2. import { defineStore } from 'pinia'
  3. import axios from 'axios';
  4. import permissions from '@/hook/permissions.json'//所有权限
  5. export const useUserCounter = defineStore('user', () => {
  6.     const userInfo = ref({})
  7.     // 获取用户信息
  8.     const setUserInfo = async () => {
  9.         await axios.get("/api/get_user_information").then(res => {
  10.             if (res.data.code === "1000") {
  11.                 userInfo.value = res.data.data
  12.             }
  13.         }, res => {
  14.             console.log('请求失败')
  15.         });
  16.     }
  17.     //清除用户信息
  18.     const clearUserInfo = () => {
  19.         userInfo.value = {}
  20.         sessionStorage.removeItem('refresh_token')
  21.         sessionStorage.removeItem('Authorization')
  22.     }
  23.     //判断是否有权限
  24.     const hasPermission = (name) =>{
  25.         let flag = false
  26.         let permissionId = null
  27.         permissions.forEach(item =>{
  28.             if(name === item.name){
  29.                 permissionId = item.id
  30.             }
  31.         })
  32.         if(permissionId && userInfo.value.permission){
  33.             if(userInfo.value.permission.split(',').indexOf((permissionId.toString())) != -1){
  34.                 flag = true
  35.             }
  36.         }
  37.         return flag
  38.     }
  39.     return { userInfo,setUserInfo,clearUserInfo,hasPermission }
  40. }, {
  41.     persist: true //持久化存储
  42. })
复制代码
  1. 其中permissions.json是所有权限的数组列表。
复制代码
二、登录获取access_token、refresh_token

  1. 登录页中先引入user.js
复制代码
  1. import {useUserCounter} from '@/stores/user'
  2. const userStore = useUserCounter()
复制代码
  1. 登录成功时将接口返回的access_token、refresh_token存入sessionStorage
复制代码
  1. ElMessage({
  2.     showClose: true,
  3.     message: "登录成功",
  4.     type: "success",
  5. });
  6. setTimeout(function () {
  7.     router.push("/");
  8.     isSubLoadding.value = false;
  9. }, 800);
  10. sessionStorage.setItem('Authorization', res.data.data.access_token)
  11. sessionStorage.setItem('refresh_token', res.data.data.refresh_token)
  12. //获取用户信息
  13. userStore.setUserInfo()
复制代码
  1. 存储token后调用setUserInfo()方法更新userInfo,包含了所有用户信息数据。
复制代码
三、给axios添加拦截器

  1. 在main.js中,引入pinia相关
复制代码
  1. import pinia from './stores/index'
  2. app.use(pinia)
  3. import { useUserCounter } from '@/stores/user'
  4. const userStore = useUserCounter()
复制代码
  1. 引入axios,设全局
复制代码
  1. import axios from 'axios'
  2. app.provide('axios', axios)
复制代码
  1. 拦截器完整代码:
复制代码
  1. // 创建一个 axios 接口
  2. const service = axios.create({
  3.     baseURL: '/api',
  4.     timeout: 5000, // 请求超时时间设置
  5.     headers: {
  6.         'Authorization': `Bearer ${sessionStorage.getItem('refresh_token')}`
  7.     }
  8. })
  9. service.setToken = (token) => {
  10.     sessionStorage.setItem('Authorization', token)
  11. }
  12. //添加请求拦截器
  13. axios.interceptors.request.use(config => {
  14.     if (sessionStorage.getItem('Authorization')) {
  15.         config.headers.Authorization = `Bearer ${sessionStorage.getItem('Authorization')}`
  16.     }
  17.     return config
  18. }, error => {
  19.     return Promise.reject(error);
  20. })
  21. let isRefreshing = false
  22. // 重试队列,每一项将是一个待执行的函数形式
  23. let requests = []
  24. axios.interceptors.response.use(response => {
  25.     const config = response.config
  26.     if (response.data.code === 401) {
  27.         if (!isRefreshing) {
  28.             isRefreshing = true
  29.             const refresh_token = sessionStorage.getItem('refresh_token')
  30.             if (refresh_token) {
  31.                 refreshToken(refresh_token).then(res => {
  32.                     const token = res.data.access_token
  33.                     service.setToken(token)
  34.                     config.headers['Authorization'] = `Bearer ${token}`
  35.                     config.baseURL = ''
  36.                     // 已经刷新了token,将所有队列中的请求进行重试
  37.                     requests.forEach(cb => cb(token))
  38.                     requests = []
  39.                     return service(config)
  40.                 }).catch(res => {
  41.                     //获取新token失败,跳转登录页
  42.                     userStore.clearUserInfo()
  43.                     router.push('/login')
  44.                 }).finally(() => {
  45.                     isRefreshing = false
  46.                 })
  47.             } else {
  48.                 userStore.clearUserInfo()
  49.                 router.push('/login')
  50.             }
  51.         }
  52.     }
  53.     return response
  54. }, error => {
  55.     return Promise.reject(error);
  56. })
  57. //获取新的token请求
  58. const refreshToken = async (token) => {
  59.     service.defaults.headers['Authorization'] = `Bearer ${token}`
  60.     return service.get('/refresh').then(res => res.data)
  61. }
复制代码
四、约束操作权限例子

  1. 引入user.js
复制代码
  1. import {useUserCounter} from '@/stores/user'
  2. const userStore = useUserCounter()
复制代码
  1. 获取userinfo
复制代码
  1. const userinfo = userStore.userInfo
复制代码
  1. 使用方法如下:
复制代码
  1. <p class="text-right m-b">
  2.    <el-button type="primary" size="small" icon="CirclePlus" @click="createMainPhase"
  3.    v-if="userStore.hasPermission('添加项目任务')">添加阶段</el-button>
  4. </p>
复制代码
  1. 给方法传对应权限参数,查询userinfo.permission中是否存在该权限,返回true/false。
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81429

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表