Skip to content

zhang13pro/login-routing

Repository files navigation

RBAC(权限系统)

  • Vue3
  • TypeScript

需求分析

  1. 实现页面导航的时候,根据登录用户所具有的权限,判断用户是否能访问该页面。
  2. 实现可见页面的局部 UI 组件的可使用性或可见性控制,即基于自定义的权限,对比声明的接口或资源是否已经授权。
  3. 实现发送请求时,传输 token,对待请求接口进行权限检查,如果用户不具有访问该后端接口的权限,则不发送请求,而是友好地提示用户。

方案

实现步骤 1 这个目标,我们的方案是:获得登录用户的可访问前端页面的 path 列表,在 router 进行导航的 beforeEach 前置钩子中,处理当前用户所能请求的页面及路由可见性。

实现 RBAC 动态权限功能思路

  1. 前端在本地写好路由表,以及每个路由对应的角色,也就是哪些角色可以看到这个菜单 / 路由;
  2. 登录时,向后端请求得到登录用户的角色(管理者,普通用户);
  3. 利用路由守卫者 router.beforeEach,根据取到的用户角色,跟本地的路由表进行对比,过滤出用户对应的路由,并利用路由进行菜单渲染。

技术实现思路

  1. 在 vue-router 的 beforeEach 方法中实现以上逻辑,判断前端跳转去向;
  2. 使用本地模拟数据的用户信息作为拦截 axios 发起的服务请求响应;
  3. 通过 window.localStorage.setItem 做 userInfo 的状态管理。

实现 RBAC 动态路由的两种方式

前端鉴权

完整的静态路由都在前端里面,然后根据 router 的 meta 属性,写上对应 user 的 role。登录时,再根据后端返回的权限,去过滤比对权限,把该用户角色所对应的路由处理好,渲染处理。

这种方式等于是把所有的路由和权限业务处理都放在了前端,一旦上线发布后,想要修改就需要重新打包处理,而且不能经由后台动态新增删除,比如:

// router/index.js
{
  path: "",
  component: layout, //整体页面的布局(包含左侧菜单跟主内容区域)
  children: [
    {
      path: "main",
      component: main,
      meta: {
        title: "首页", //菜单名称
        roles: ["user", "admin"], //当前菜单哪些角色可以看到
      },
    },
  ],
}

后端鉴权

前端把用户输入的账号密码传递给后端,后端根据用户输入的账号密码,做鉴权和路由角色处理,然后把匹配了对应用户的路由返回给前端,再由前端去渲染路由和页面。这样的做法就是把所有的计算和处理都让后端去实现了,前端运算量不会太大,而且易于修改和后期维护以及动态的增删改查。

具体实现

这里采用第二种方式,也就是后端鉴权。

第一步:根据路由表,判断哪些用户可以看到对应的路由和权限

routes 配置区分 admin 管理员和 people 普通用户的差异化动态路由了,admin 多了一个 admin 的页面,而 people 是没有的。

第二步:模拟用户登录,获取用户的权限和路由

由于我们是 mock 出来的数据,所以 dynamicUser 是用户角色的数组形式,所以需要定义一个变量( flag )用以做登录校验匹配,如果循环都找不到对应的 username 和 password 的话,就告诉用户,该账号密码错误,登录失败。否则返回对应的用户信息,用户路由等,最后还会进行路由的跳转初始化页面(首页),并进行动态路由加载和路由跳转。(在这里,必须要先做路由跳转,然后 router 的 beforeEach 才能捕获到路由的变化状态,进行路由的动态加载。)

第三步:根据登录返回的数据,实现路由守卫

路由守卫者拦截 beforeEach,并动态渲染出路由表。

About

Vue3 & element-plus & Vue-Router

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published