前端权限管理思路

前言

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

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

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

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

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

权限关系

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;
相关推荐
kyriewen13 小时前
豆包和千问同时关了智能体,我用它们搭的 3 个自动化全废了——迁移方案整理
前端·javascript·ai编程
前端一小卒13 小时前
我用 TypeScript 从零手写了一个 Claude Code,然后发现它的核心只有 30 行
前端·agent
大圣编程15 小时前
Python中continue语句的用法是什么?
开发语言·前端·python
yuhaiqiang15 小时前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
之歆16 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
再吃一根胡萝卜16 小时前
如何把小米 MiMo 接入 CodeBuddy,打造私有 Agent
前端
负责的蛋挞17 小时前
异步HttpModule的实现方式
java·服务器·前端
丹宇码农20 小时前
把 HLS 字幕玩出花:zwPlayer 如何让 M3U8 视频支持全文搜索、翻译与码率自适应
前端·javascript·音视频·hls·视频播放器
2501_9437823520 小时前
【共创季稿事节】猜数字游戏:二分法思维与交互式反馈
前端·游戏·microsoft·harmonyos·鸿蒙·鸿蒙系统