RBAC权限设计详解

article/2025/9/16 8:07:36

权限设置

1.权限点

  • 权限:在一个系统内是否具有做某个操作的权利
  • 权限分为两个级别

             1. 菜单权限:是否有权限访问某个菜单

             2.按钮权限:是否有权限操作 页面上的某个按钮功能

2.业务逻辑

对于权限数据来说,有两个级别的设置

1.能不能访问谋个页面

2.在页面上,能不能操作某个按钮

3.RBAC权限设计思想

目标:不同账号登录系统后看到不同的页面, 能执行不同的功能

模式如下

 

三个关键点:

用户: 就是使用系统的人

权限点:这个系统中有多少个功能(例始:有3个页面,每个页面上的有不同的操作)

角色:不同的权限点的集合

实际上就是

  1. 给用户分配角色
  2. 给角色分配权限点

实际业务中:

  1. .先给员工分配一个具体的角色         
  2. 然后给角色分配具体的权限点 (工资页面 工资页面下的操作按钮)员工就拥有了权限点

4.权限具体业务

示例:

 

具体步骤

1.动态生成左侧菜单-addRoutes方法

在router中直接静态写死的动态路由表改造成通过addRoutes 方法调用添加的形式

// 引入所有的动态路由表(未经过筛选)
import router, { asyncRoutes } from '@/router'
const whiteList = ['/login', '/404']
router.beforeEach(async(to, from, next) => {NProgress.start() // 启动进度条if (store.getters.token) {if (to.path === '/login') {next('/')} else {if (!store.getters.userId) {// 判断userInfo有没有id值,如果没有就进user/getUserInfoconst menus = await store.dispatch('user/getUserInfo')console.log('当前用户可以访问的权限是', menus)// 根据用户的实际权限menus,可以在asyncRoutes筛选出用户可以访问的权限const filterRoute = asyncRoutes.filter(route => {return menus.includes(route.children[0].name)})// 因为404页面在路由的中间位置,要进去之前404路由后面的路由时,直接进404页面了// 把404路由添加到所有路由的末尾就可以解决这个问题filterRoute.push( // 404 page must be placed at the end !!!{ path: '*', redirect: '/404', hidden: true })// 改写成动态添加路由// addRoutes用来动态添加路由配置// 只有在这里设置了补充路由配置,才能去访问页面,如果没有设置的话,左边的菜单不显示的router.addRoutes(filterRoute)// 把他们保存到vuex中,在src\layout\components\Sidebar\index.vue// 生成左侧菜单时,也应该去vuex中拿store.commit('menu/setMenuList', filterRoute)// 解决刷新出现的白屏bugnext({...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)replace: true // 重进一次, 不保留重复历史})} else {next()}}} else {if (whiteList.includes(to.path)) {next()} else {next('/login')}}
})

我们发现左侧的菜单只剩下静态的首页了,浏览器手动输入某一个动态路由地址,依旧是可用的,这证明我们其实已经把动态路由添加到我们的路由系统了。

2.动态生成左侧菜单-改写菜单保存位置

当前的菜单渲染使用的数据:this.$router.options.routes 这个数据是固定,addRoutes添加的路由表只存在内存中,并不会改变this.$router.options.routes

目标:调用router.addRoutes() , 想要数据反映到视图上, 将路由信息存在vuex中

2.1定义vuex管理菜单数据

在src/store/modules下补充menu.js :

// 导入静态路由
import { constantRoutes } from '@/router'
export default {namespaced: true,state: {// 先以静态路由作为菜单数据的初始值menuList: [...constantRoutes]},mutations: {setMenuList(state, asyncRoutes) {// 将动态路由和静态路由组合起来state.menuList = [...constantRoutes, ...asyncRoutes]}}
}

src/store/index.js中注册这个模块

2.2提交setMenuList生成完整的菜单数据

修改src/permission.js:

if (!store.getters.userId) {await store.dispatch('user/getUserInfo')// 把动态路由数据交给菜单store.commit('menu/setMenuList', asyncRoutes)// 把动态路由添加到应用的路由系统里router.addRoutes(asyncRoutes)
}

2.3菜单生成部分改写使用vuex中的数据

routes() {// 拿到的是一个完整的包含了静态路由和动态路由的数据结构// return this.$router.options.routesreturn this.$store.state.routeMenu.menuList
}

3.使用权限数据做过滤处理

  1. 通过后台返回的权限数据, 过滤出要显示的菜单, 过滤使用路由的name作为标识
  2. 从action中获取返回值
    action本质上是一个promise 它的return 结果可以通过const res = await action名来接收

     

  3. 修改 store/modules/user.js

// 用来获取用户信息的actionasync getUserInfo(context) {// 1. ajax获取基本信息,包含用户idconst rs = await getUserInfoApi()console.log('用来获取用户信息的,', rs)// 2. 根据用户id(rs.data.userId)再发请求,获取详情(包含头像)const info = await getUserDetailById(rs.data.userId)console.log('获取详情', info.data)// 把上边获取的两份合并在一起,保存到vuex中context.commit('setUserInfo', { ...info.data, ...rs.data })return rs.data.roles.menus},

       4.在permission.js中过滤

if (!store.getters.userId) {// 有token,要去的不是login,就直接放行// 进一步获取用户信息// 发ajax---派发action来做const menus = await store.dispatch('user/getUserInfo')console.log('当前用户能访问的页面', menus)console.log('当前系统功能中提供的所有的动态路由页面是', asyncRoutes)// 根据本用户实际的权限menus去 asyncRoutes 中做过滤,选出本用户能访问的页面const filterRoutes = asyncRoutes.filter(route => {const routeName = route.children[0].namereturn menus.includes(routeName)})// 一定要在进入主页之前去获取用户信息// addRoutes用来动态添加路由配置// 只有在这里设置了补充了路由配置,才可能去访问页面// 它们不会出现左侧router.addRoutes(filterRoutes)// 把它们保存在vuex中,在src\layout\components\Sidebar\index.vue// 生成左侧菜单时,也应该去vuex中拿store.commit('menu/setMenuList', filterRoutes)// 解决刷新出现的白屏bugnext({...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)replace: true // 重进一次, 不保留重复历史})}

注意事项

  • 解决404问题
    原因:现在我们的路由设置中的404页处在中间位置而不是所有路由的末尾了
    解决办法:把404页改到路由配置的最末尾就可以了
    1. 从route/index.js中的静态路由中删除path:’*'这一项
    2. 在permission.js中补充在最后

代码示例:

    if (!store.getters.userId) {// 有token,要去的不是login,就直接放行// 进一步获取用户信息// 发ajax---派发action来做const menus = await store.dispatch('user/getUserInfo')console.log('当前用户能访问的页面', menus)console.log('当前系统功能中提供的所有的动态路由页面是', asyncRoutes)// 根据本用户实际的权限menus去 asyncRoutes 中做过滤,选出本用户能访问的页面const filterRoutes = asyncRoutes.filter(route => {const routeName = route.children[0].namereturn menus.includes(routeName)})// 一定要在进入主页之前去获取用户信息// 把404加到最后一条filterRoutes.push( // 404 page must be placed at the end !!!{ path: '*', redirect: '/404', hidden: true })// addRoutes用来动态添加路由配置// 只有在这里设置了补充了路由配置,才可能去访问页面// 它们不会出现左侧router.addRoutes(filterRoutes)// 把它们保存在vuex中,在src\layout\components\Sidebar\index.vue// 生成左侧菜单时,也应该去vuex中拿store.commit('menu/setMenuList', filterRoutes)// 解决刷新出现的白屏bugnext({...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)replace: true // 重进一次, 不保留重复历史})} 
  • 退出时重置路由

router/index.js中

// 重置路由
export function resetRouter() {const newRouter = createRouter()router.matcher = newRouter.matcher // 重新设置路由的可匹配路径
}

这个方法就是将路由重新实例化,相当于换了一个新的路由,之前加的路由就不存在了,需要在登出的时候, 调用一下即可

import { resetRouter } from '@/router'
// 退出的action操作
logout(context) {// 1. 移除vuex个人信息context.commit('removeUserInfo')// 2. 移除token信息context.commit('removeToken')// 3. 重置路由resetRouter()// 4. 重置 vuex 中的路由信息 只保留每个用户都一样的静态路由数据//    在moudules中的一个module中去调用另一个modules中的mutation要加{root:true}context.commit('setMenuList', [], { root: true })
}

4.控制操作按钮

思路

 定义全局检测的方法:

Vue.prototype.$checkPoint = function(pointKey) {if (store.state.user.userInfo.roles.points) {// 进行权限点判断return store.state.user.userInfo.roles.points.includes(pointKey)}// 没有权限点POINTS信息, 说明用户没有身份, 没有任何权限return false
}

在模板中通过if来控制按钮显示

<template><div class="dashboard-container"><div class="app-container"><el-card><el-button v-if="$checkPoint('CKGZ')">查看工资</el-button></el-card></div></div>
</template>

 $checkPoint中的参数以系统中权限点的标识符为准。

或者自定义指令控制按钮显示

在main.js中定义全局指令

// 注册一个全局自定义指令 `v-allow`
Vue.directive('allow', {// 当被绑定的元素插入到 DOM 中时……inserted: function(el, binding) {// v-focus="'abc'"  ===> binding.value = 'abc'if (store.state.user.userInfo.roles.points.includes(binding.value)) {// 元素是可见的} else {el.style.display = 'none'}}
})

使用

<el-buttonv-allow="'import_employee'"type="warning"size="small"@click="$router.push('/import')">导入excel</el-button>

 

目录

权限设置

1.权限点

2.业务逻辑

3.RBAC权限设计思想

4.权限点

具体步骤

1.动态生成左侧菜单-addRoutes方法

2.动态生成左侧菜单-改写菜单保存位置

3.使用权限数据做过滤处理

4.控制操作按钮



http://chatgpt.dhexx.cn/article/6BdjRxVI.shtml

相关文章

RBAC 模型是什么?

RBAC 模型是什么? 美国国家标准与技术研究院&#xff08;The National Institute of Standards and Technology&#xff09;认为 RBAC 模型由 4 个基础模型组成&#xff1a; 1. 基本模型 RBAC0&#xff08;Core RBAC&#xff09;2. 角色分层模型 RBAC1&#xff08;Hierarcha…

什么是RBAC?

什么是RBAC&#xff1f; 全称&#xff1a;role-based access control 基于角色的权限访问控制 作用&#xff1a;实现访问控制 RBAC模型概括 RBAC权限授权的过程可以概括为&#xff1a;W是否可以对Z进行H的访问操作&#xff0c;并对这个逻辑表达式进行判断是否为true的过程&…

RBAC(一)

介绍 RBAC(基于角色的权限控制&#xff0c;role base access control)是一种设计模式&#xff0c;用于设计和管理权限相关数据的一种模型。 RBAC认为权限授权的过程可以抽象地概括为&#xff1a;Who是否可以对What进行How的访问操作&#xff0c;并对这个逻辑表达式进行判断是否…

RBAC浅谈(一)RBAC的基本概念

1.概念 RBAC即Role Based Access Control&#xff0c;意为基于角色的访问控制。用户与角色相关联&#xff0c;当用户在系统进行注册时可以选择成为某一角色从而拥有这个角色的权限&#xff0c;当然新注册的用户的权限也可以由上一级用户授予如管理员认定某个用户为某个角色就授…

RBAC权限详解

RBAC权限详解 权限设置 1.权限点 权限:在一个系统内是否具有做某个操作的权利 权限分为两个级别 1. 菜单权限:是否有权限访问某个菜单2. 按钮权限:是否有权限操作 页面上的某个按钮功能2.业务逻辑 对于权限数据来说,有两个级别的设置 1.能不能访问谋个页面 2.在页面上,能…

Rbac权限管理--如何设计

RBAC&#xff08;Role-Based Access Control&#xff0c;基于角色的访问控制&#xff09;&#xff0c;就是用户通过角色与权限进行关联。简单地说&#xff0c;一个用户拥有若干角色&#xff0c;每一个角色拥有若干权限。这样&#xff0c;就构造成“用户-角色-权限-资源”的授权…

六,RBAC简介

六&#xff0c;RBAC RBAC&#xff08;基于角色的权限控制 role base access control&#xff09;是一种设计模式&#xff0c;是用来设计和管理权限相关数据的一种模型 RBAC权限数据的管理&#xff0c;都是重复的CRUD的操作&#xff0c;这里我们就不再重复的从0到1开发&#xf…

RBAC简介

目录 RBAC简介RBAC0RBAC1RBAC2RBAC3 RBAC简介 RBAC是Role Based Access Control的英文缩写&#xff0c;意思是基于角色访问控制。 RBAC实际上就是针对产品去发掘需求时所用到的Who&#xff08;角色&#xff09;、What&#xff08;拥有什么资源&#xff09;、How&#xff08;有…

RBAC 权限

RBAC权限分析 RBAC 全称为基于角色的权限控制&#xff0c;本段将会从什么是RBAC&#xff0c;模型分类&#xff0c;什么是权限&#xff0c;用户组的使用&#xff0c;实例分析等几个方面阐述RBAC 什么是RBAC RBAC 全称为用户角色权限控制&#xff0c;通过角色关联用户&#xff…

RBAC模型

最近开始在找java项目&#xff0c;大部分时间都是跟着视频或者代码一步一步敲过来&#xff0c;但是对代码的理论层面还是有所欠缺&#xff0c;今天就来分享一个系统设计中的一个模型。不管是哪一个系统&#xff0c;都绕不开权限控制&#xff0c;因为现在的角色太多了&#xff0…

RBAC入门教程及实例演示

RBAC 一、RBAC的作用 在很多系统中&#xff0c;会要求不同的账户对应着不同的角色和权限。如教务管理系统&#xff0c;分为以下几种功能&#xff0c;不同的功能对应着不同的角色 如果要做到登录后根据账户的角色&#xff0c;给出相应的菜单&#xff0c;及规定当前角色只能做出…

RBAC简介(*)

一.RBAC是什么 1.RBAC模型概述 RBAC是Role Based Access Control的英文缩写&#xff0c;意思是 基于角色的访问控制。 RBAC实际上就是针对产品去挖掘需求时所用到的Who&#xff08;角色&#xff09;、What&#xff08;拥有什么资源&#xff09;、How&#xff08;有哪些操作&am…

什么是 RBAC 模型?

前言 RBAC&#xff08;Role-Based Access Control&#xff09;&#xff0c;基于角色的访问控制&#xff0c;现在主流的权限管理系统的权限设计都是 RBAC 模型&#xff0c;或者是 RBAC 模型的变形。 我们需要思考一个问题&#xff1a;为什么要做权限的管理&#xff1f; 我的理…

RBAC权限管理(详细)

RBAC权限设计思想 为了达成不同账号(员工、总裁)登录系统后看到不同页面&#xff0c;执行不同功能&#xff0c;RBAC(Role-Based Access control)权限模型&#xff0c;就是根据角色的权限&#xff0c;分配可视页面。 三个关键点: 用户:使用系统的人 角色&#xff1a;使用系统…

什么是RBAC

一、RBAC是什么 1、RBAC模型概述 RBAC模型&#xff08;Role-Based Access Control&#xff1a;基于角色的访问控制&#xff09;模型是20世纪90年代研究出来的一种新模型&#xff0c;但其实在20世纪70年代的多用户计算时期&#xff0c;这种思想就已经被提出来&#xff0c;直到…

最小生成树,秒懂!

&#x1f447;&#x1f447;关注后回复 “进群” &#xff0c;拉你进程序员交流群&#x1f447;&#x1f447; 作者丨bigsai 来源丨bigsai 前言 在数据结构与算法的图论中&#xff0c;(生成)最小生成树算法是一种常用并且和生活贴切比较近的一种算法。但是可能很多人对概念不是…

算法 - 最小生成树实现

算法能力是一个门槛&#xff0c;也是个有基础的门槛 无论你是iOS工程师&#xff0c;android工程师&#xff0c;java工程师&#xff0c;前端&#xff0c;后端还是全栈等等… 算法能力的强弱一方面在于思想&#xff0c;你是否有计算机思维抽象具体问题的能力 更重要的还在与基…

最小树形图(有向图的最小生成树)

我们知道&#xff0c;无向图的最小生成树的求法有Krusal和prime算法&#xff0c;一个是归点一个是归边&#xff0c;在具体实现上Krusal可以用并查集实现&#xff0c;难度不大。 这里稍微区别一下最短路径和最小生成树&#xff08;因为我又搞混了23333&#xff09; 最小生成树能…

Kruskal算法(最小生成树)

上篇Prim算法简要的讲解了最小生成树。也提到过Prim算法堆优化&#xff0c;但本蒟蒻并没有贴Prim &#xff08;堆优化的代码&#xff09;。至于为什么没有贴呢&#xff1f;上篇Prim算法blog末尾有说明。 好勒&#xff01;咱们接着讲Kruskal算法。这跟Prim算法有很大的…

最小生成树matlab求解

一、最小生成树 连通所有顶点且总路径最小修建连通7个城市的铁路网&#xff0c;可修建的路线和对应造价如图所示&#xff0c;如何修建使总费用最少&#xff1f; 问题分析&#xff1a; 连通7个城市&#xff1a;生成的图中&#xff0c;从任意顶点起步&#xff0c;沿着边一定可以…