前端权限管理思路

前言

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

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

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

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

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

权限关系

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;
相关推荐
啃火龙果的兔子2 分钟前
前端八股文-vue篇
前端·javascript·vue.js
孜然卷k8 分钟前
前端处理后端对象类型时间格式通用方法封装,前端JS处理JSON 序列化后的格式 java.time 包中的日期时间类
前端·json
幼儿园技术家12 分钟前
微信小程序实现用户进行推客的注册绑定
前端
gwcgwcjava15 分钟前
[技术积累]成熟的前端和后端开发框架
前端
bbsh209917 分钟前
SiteAzure:SetCookie 未设置Secure
前端·网络·安全·siteazure
Mintopia33 分钟前
计算机图形学环境贴图(Environment Mapping)教学指南
前端·javascript·计算机图形学
码农之王35 分钟前
(二)TypeScript前置编译配置
前端·后端·typescript
spmcor37 分钟前
css 之 Flexbox 的一生
前端·css
Mintopia40 分钟前
Three.js 高级纹理(Advanced Textures):超越基础,打造沉浸式 3D 世界
前端·javascript·three.js
玄玄子40 分钟前
JS Promise
前端·javascript·程序员