前端权限管理思路

前言

要弄清楚这个问题,我们先来看看什么是权限?个人认为,权限就是一系列用户可用的系统资源的整合,可以大致分为以下三类:

  • 菜单权限:用户使用的菜单、查看的页面等。
  • 操作权限:系统页面中的交互功能按钮,如编辑,删除,新增等。
  • 数据权限:用户在页面中查看的数据内容,业务系统数据一般存在机密性,不同身份的用户查看的数据范围也有所不同。

了解了权限 ,那么 权限管理 也就比较清晰了,其实就是对系统用户访问资源的管理。根据业务要求的不同,用户看到的菜单、使用的功能、查看的数据都有所不同。

那么为什么要控制访问权限呢?因为不同的用户所负责的业务范围是不同的,比如管理者可以看到所有下属的信息,但是普通只能看到自己的;比如行政可以看到所有人的打卡记录,而普通员工只能看自己的;比如财务可以看到所有人的工资,而普通员工只能看到自己的....等等等等,

这都离不开 权限管理,通过为系统用户分配不同的权限,以达到精准控制的目的。

权限关系

1.角色和人员: 一个角色可以包含但不限于一个成员,一个成员可以被分配至多个权限角色中(取和值,即取多个角色权限的和值)

2.角色和菜单: 多对多关系:一个角色有多个菜单,一个菜单可以分配给多个角色

3.角色和权限资源管理: 多对多关系:一个角色有多个权限资源,一个权限资源可以分配给多个角色

思路跟方案

1.当用户开始访问

2.用户登录成功(并且拉取权限接口)

3.降权限数据保存到session中

4.根据获取的权限,对当前的路由进行序列化,不在该用户权限内的菜单排除序列化

5.文件目录和结构

css 复制代码
├── src
	├──	api
		└── sys.rbac.service.js
	├──	directive
		├── directives.js
		└── index.js
	├── layout
		├── components/Sidebar
			└── index.js
	├── router
		└── index.js
	├── store
		├──	modules
			└── permission.js
		└──	getters.js
	├── main.js
	└── permission.js

序列化代码如下

permission.js 复制代码
const component = modules[`你的组件路径`]?.default;
const route = {
  path: path,
  name: path + item.name,
  meta: {
    title: item.name,
    svgIcon: 'dashboard',
    affix: false,
  },
};

路由js(router.js),异步加入路由菜单信息

js 复制代码
permissionStore.dynamicRoutes.forEach((route: any) => {
   router.addRoute(route);
});

permission指令注册

js 复制代码
/** 权限指令,和权限判断函数 checkPermission 功能类似 */
export const permission: Directive = {
  mounted(el, binding) {
    const { value: permissionRoles } = binding;
    const { roles } = useUserStoreHook();
    if (Array.isArray(permissionRoles) && permissionRoles.length > 0) {
      const hasPermission = roles.some((role) => permissionRoles.includes(role));
      // hasPermission || (el.style.display = "none") // 隐藏
      hasPermission || el.parentNode?.removeChild(el); // 销毁
    } else {
      throw new Error(`need roles! Like v-permission="['admin','editor']"`);
    }
  },
};

使用办法

js 复制代码
<el-button
  v-permission="['TRAINING:PLAN:UPDATE@PUT']"
  type="primary"
  >编辑</el-button
>

加入路由白名单

whiteList.js 复制代码
import { type RouteLocationNormalized } from 'vue-router';

/** 免登录白名单(匹配路由 path) */
const whiteListByPath: string[] = ['/login'];

/** 免登录白名单(匹配路由 name) */
const whiteListByName: string[] = [];

/** 判断是否在白名单 */
const isWhiteList = (to: RouteLocationNormalized) => {
  // path 和 name 任意一个匹配上即可
  return whiteListByPath.indexOf(to.path) !== -1 || whiteListByName.indexOf(to.name as any) !== -1;
};

export default isWhiteList;
相关推荐
程序员黑豆11 分钟前
鸿蒙应用开发:@Link 装饰器实现父子组件双向同步
前端·后端·harmonyos
前端炒粉12 分钟前
简易实现ssr
开发语言·前端·javascript
顶级自由人25 分钟前
【前端菜鸟的补课01】Zod 与 PostgreSQL 全栈数据工程教学
前端·后端·程序员
swipe42 分钟前
11|(前端转全栈)购物车不能只存在前端:用户维度数据如何在后端落库
前端·后端·全栈
Chengbei113 小时前
云安全漏洞挖掘SKILL、一站式云漏洞挖掘工具,支持S3爆破、IMDS探测、K8s检测与AK/SK权限利用
前端·人工智能·网络安全·云原生·容器·kubernetes·系统安全
不简说3 小时前
JS 代码技巧 vol.9 — 20 个设计模式在真实项目里的应用
前端·javascript·github
CoderLiu3 小时前
Agent 工程的下一层:为什么「把流程写成图」还不够,还需要 Graph Engineering
前端·人工智能·后端
勇往直前plus3 小时前
Vue3(篇三) Element Plus
前端·javascript·typescript·vue
爱勇宝4 小时前
《道德经》第 8 章:真正高级的能力,像水一样成事
前端·后端·程序员
Revolution614 小时前
数组本身没有 map,为什么还能直接调用:原型链怎样查找属性
前端·javascript·面试