路由权限的分类与踩坑记录

路由权限的分类与踩坑记录

路由的权限控制基本上分为两种,一种是完全由后端进行控制与分配权限,第二种是前端进行权限设置然后发送给后端,然后每次在登陆的时候调用这个路由权限的数组接口,根据这个接口的路由与基础路由进行合并。

1.后端进行控制与分配

在前端设置路由的时候,根据路由中是否有logIn_marking来判断是否需要需要进行权限判定,

css 复制代码
{
            path: 'router-face-swap-template',
            name: 'faceSwapV2',
            meta: {
                title: '',
                login_marking: 'faceSwapV2',
                showName: '图片换脸V2'
            },
            component: (resolve) => import('./views/ai-face/face-swap-template/index.vue'),
        }

如果有这个参数,则需要判定该用户是否有这个路由的权限,如果没有这个参数,则代表是常态路由,不需要进行判定,实现的时候用的是路由守卫的方式,将login_marking传到登录的仓库当中,进行islogin的判定

javascript 复制代码
router.beforeEach((to, from, next) => {
    // 拦截没有权限是路由
    ViewUI.LoadingBar.start();
    Util.title(to.meta.title);
    if (to.meta.login_marking) {
        if (!useUserStore(pinia).isLogin(to.meta.login_marking)) {
            console.log('need login')
            next({
                path: `router-login?redirect=${to.name}`,
                replace: true
            })
            return
        }
        console.log('LOGINED')
    }
    next();
});

router.afterEach((to, from, next) => {
    ViewUI.LoadingBar.finish();
    window.scrollTo(0, 0);
});

store中存储了登录信息和计算属性getters,将点击某个路由的login_marking传入到计算属性当中,进行判定,由于是数组数字,所以要加上映射,如果点击的路由在用户数组内,则代表该用户有这个权限。如果用户中没有则重定向到登录页面

javascript 复制代码
    state: () => {
        return {
            menus: [],
            roles: [],
            id: null,
            name: '',
            currentMenu: null,
        }
    },
    getters: {
        isLogin(state) {
            return (mark) => state.roles.includes(menuMap[mark])
        }
    },
arduino 复制代码
// 菜单权限map

export const menuMap = {
    aiFaceFusion: '9',
    aiFaceReplace: '8',
    aiFaceEmotion: '7',
    aigcConfig: '10',
    aigcMultiTest: '11',
    firstDayMail: '12',
    faceSwapV2: '13',
    aiLivePortrait: '14',
    aliemo: '15',
    vidu: '16',
}

2.前端端进行控制与分配

前端进行异步权限的设置会生成一个数组,根据接口传递给后端存储,每次登录的时候采用store中得到路由信息,由于是树状结构,因此采用递归的方法进行数组过滤,过滤出需要的数组路由,

typescript 复制代码
const filterAsyncRoute = (asyncRoute: any, routes: any) => {
  return asyncRoute.filter((item: any) => {
    if (routes.includes(item.name)) {
      if (item.children && item.children.length) {
        item.children = filterAsyncRoute(item.children, routes)
      }
      return true
    }
  })
}

然后将常态路由和遍历出的异步路由进行拼接,得到所有的路由,然后赋值给用户

typescript 复制代码
 // 获取用户信息
    async userInfo() {
      const result: userInfoResponseData = await reqUserInfo()
      if (result.code === 200) {
        this.username = result.data.name
        this.avatar = result.data.avatar
        const userAsyncRoute = filterAsyncRoute(
          cloneDeep(asyncRoute),
          result.data.routes,
        )
        const arr = [...userAsyncRoute, ...anyRoute]
        this.menuRoutes = [...constantRoute, ...arr]
        arr.forEach((item: any) => {
          router.addRoute(item)
        })
        return 'ok'
      } else {
        return Promise.reject(new Error(result.message))
      }
    },

踩坑记录1:跳转页面后404

当改变地址栏或者刷新页面的时候,页面会跳转到404,这是由于路由没有找到强匹配的地址,就会跳转到404页面

javascript 复制代码
    {
      path: '/404',
      name: '404',
      component: () => import('@/views/404'),
      hidden: true
    },
    {
      path: '*',
      redirect: '/404',
      hidden: true
    }

不在初始化路由的时候初始化,而是在解析接收的路由数据时拼接路由

javascript 复制代码
// 将生成数组树结构的菜单并拼接404路由
  const routes = Object.values(menusMap).concat(notFoundRoutes)

踩坑记录2:数据无法持久化

刷新页面会发现页面变空白,这是由于刷新页面router实例会重新初始化到初始状态,因此需要使用sessionstorage进行数据持久化

arduino 复制代码
export const useUserStore = defineStore('useUserStore', {
    // 开启数据缓存
    persist: {
        storage: sessionStorage,
    },
相关推荐
b1gbrother1 分钟前
让你的Claude Code变得更聪明
前端·程序员
国家不保护废物10 分钟前
多模态模型数据传输的秘密武器:html5对象Blob深度解析
前端·面试·html
用户25191624271110 分钟前
Canvas之概述,画布与画笔
前端·javascript·canvas
南方kenny10 分钟前
前端小知识:搞懂 BFC块级格式化上下文,告别面试“拦路虎”!
前端·css·面试
邵洛11 分钟前
前端导出excel表格并修改导出表格样式
前端
风舞11 分钟前
JavaScript 核心概念及代码示例的梳理
前端
学长学姐我该怎么办13 分钟前
从零开始学前端html篇2
前端·html
尘世中一位迷途小书童14 分钟前
从零实现 Canvas 图形拖拽:让你的网页动起来!
前端
mrsk15 分钟前
JavaScript之变量的解构赋值全面解析(●'◡'●)
前端·javascript·面试
归于尽15 分钟前
回调函数在Node.js中是怎么执行的?
前端·javascript·node.js