当前位置: 首页 > news >正文

RuoYi系统角色权限划分与控制

RuoYi 采用RBAC(基于角色的访问控制)模型,核心关系:用户 → 角色 → 菜单/权限(按钮)。权限字符串格式为系统:模块:操作(如system:user:add)。下面分权限划分、页面权限、按钮权限、后端接口权限四部分说明,并附完整可运行代码示例。


一、角色与权限划分(核心模型)

1. 数据库表关系(核心)

  • sys_user:用户
  • sys_role:角色
  • sys_menu:菜单/按钮(含权限字段perms
  • sys_user_role:用户 ↔ 角色关联
  • sys_role_menu:角色 ↔ 菜单/按钮关联

2. 权限级别

  1. 菜单权限:控制左侧菜单是否显示(页面级)
  2. 按钮权限:控制页面内按钮/元素显示(元素级)
  3. 接口权限:后端接口访问控制(API 级)
  4. 数据权限:控制数据范围(部门/本人等)

3. 权限标识规范

系统:模块:操作 system:user:list # 用户列表 system:user:add # 新增 system:user:edit # 编辑 system:user:remove # 删除 system:user:export # 导出 *:*:* # 超级管理员(所有权限)

二、页面(路由)权限控制

1. 前端路由守卫(Vue 版)

src/permission.js(路由拦截)

importrouterfrom'./router'import{ElMessage}from'element-plus'importuseUserStorefrom'@/store/modules/user'// 白名单constwhiteList=['/login','/register']router.beforeEach((to,from,next)=>{constuserStore=useUserStore()// 已登录if(userStore.token){if(to.path==='/login'){next({path:'/'})}else{// 判断是否有用户信息if(userStore.permissions.length===0){// 获取用户信息、权限userStore.getInfo().then(()=>{next({...to,replace:true})}).catch(err=>{userStore.logout().then(()=>{ElMessage.error(err||'权限校验失败')next('/login')})})}else{next()}}}else{// 未登录if(whiteList.includes(to.path)){next()}else{next('/login')}}})

2. 动态路由(后端返回菜单)

src/store/modules/user.js(获取权限)

import{login,logout,getInfo}from'@/api/login'import{defineStore}from'pinia'constuseUserStore=defineStore('user',{state:()=>({token:localStorage.getItem('token')||'',permissions:[],// 权限标识集合roles:[]// 角色集合}),actions:{// 获取用户信息getInfo(){returnnewPromise((resolve,reject)=>{getInfo().then(res=>{constuser=res.user// 超级管理员if(user.userId===1){this.permissions=['*:*:*']}else{this.permissions=res.permissions}this.roles=res.rolesresolve(res)}).catch(err=>reject(err))})}}})

三、按钮(元素)权限控制(最常用)

1. 自定义指令v-hasPermi(核心)

(1)指令定义:src/directive/permission/hasPermi.js
importuseUserStorefrom'@/store/modules/user'exportdefault{mounted(el,binding){const{value}=bindingconstall_permission="*:*:*"constuserStore=useUserStore()constpermissions=userStore.permissionsif(value&&Array.isArray(value)&&value.length>0){// 判断是否有权限consthasPermission=permissions.some(perm=>{returnall_permission===perm||value.includes(perm)})// 无权限则移除元素if(!hasPermission){el.parentNode&&el.parentNode.removeChild(el)}}else{thrownewError(`请设置权限标识,如 v-hasPermi="['system:user:add']"`)}}}
(2)指令注册:src/directive/index.js
importhasPermifrom'./hasPermi'importhasRolefrom'./hasRole'exportdefaultfunctiondirective(app){app.directive('hasPermi',hasPermi)// 权限指令app.directive('hasRole',hasRole)// 角色指令}
(3)全局注册:src/main.js
import{createApp}from'vue'importAppfrom'./App.vue'importdirectivefrom'./directive'constapp=createApp(App)directive(app)// 注册所有指令app.mount('#app')

2. 页面按钮使用示例(Vue 模板)

<template> <div> <!-- 单个权限:新增按钮 --> <el-button type="primary" icon="plus" v-hasPermi="['system:user:add']" @click="handleAdd" > 新增用户 </el-button> <!-- 单个权限:编辑按钮 --> <el-button type="success" icon="edit" v-hasPermi="['system:user:edit']" @click="handleEdit" > 编辑 </el-button> <!-- 多个权限满足其一 --> <el-button type="warning" v-hasPermi="['system:user:export', 'system:user:view']" > 导出/查看 </el-button> <!-- 角色控制:仅 admin 可见 --> <el-button type="danger" v-hasRole="['admin']" @click="handleDelete" > 删除 </el-button> </div> </template>

3. 表格操作列示例

<el-table-column label="操作" width="180"> <template #default="scope"> <el-button size="mini" text icon="edit" v-hasPermi="['system:user:edit']" @click="handleEdit(scope.row)" > 编辑 </el-button> <el-button size="mini" text icon="delete" v-hasPermi="['system:user:remove']" @click="handleDelete(scope.row)" > 删除 </el-button> </template> </el-table-column>

四、后端接口权限控制(Spring Boot 版)

1. 注解方式(@PreAuthorize/@RequiresPermissions

(1)Controller 层(页面/按钮对应接口)
@RestController@RequestMapping("/system/user")publicclassSysUserController{/** * 查询用户列表(页面权限) */@PreAuthorize("hasPermission('system:user:list')")@GetMapping("/list")publicTableDataInfolist(SysUseruser){startPage();List<SysUser>list=userService.selectUserList(user);returngetDataTable(list);}/** * 新增用户(按钮权限) */@PreAuthorize("hasPermission('system:user:add')")@PostMappingpublicAjaxResultadd(@RequestBodySysUseruser){returntoAjax(userService.insertUser(user));}/** * 修改用户(按钮权限) */@PreAuthorize("hasPermission('system:user:edit')")@PutMappingpublicAjaxResultedit(@RequestBodySysUseruser){returntoAjax(userService.updateUser(user));}/** * 删除用户(按钮权限) */@PreAuthorize("hasPermission('system:user:remove')")@DeleteMapping("/{userIds}")publicAjaxResultremove(@PathVariableLong[]userIds){returntoAjax(userService.deleteUserByIds(userIds));}}
(2)权限实现:UserRealm(Shiro 版)
publicclassUserRealmextendsAuthorizingRealm{@OverrideprotectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){SysUseruser=ShiroUtils.getSysUser();SimpleAuthorizationInfoinfo=newSimpleAuthorizationInfo();// 超级管理员if(user.isAdmin()){info.addStringPermission("*:*:*");}else{// 获取用户权限Set<String>perms=menuService.selectPermsByUserId(user.getUserId());info.setStringPermissions(perms);}returninfo;}}

五、权限配置(后台操作)

  1. 菜单管理:新增菜单/按钮,填写权限字符(如system:user:add
  2. 角色管理:给角色分配菜单/按钮权限
  3. 用户管理:给用户分配角色

六、总结

  • 页面权限:路由守卫 + 动态菜单
  • 按钮权限v-hasPermi自定义指令(前端隐藏)
  • 接口权限@PreAuthorize(后端拦截)
  • 权限字符串系统:模块:操作,统一易维护
http://www.cnnetsun.cn/news/1820767.html

相关文章:

  • 从手机充电到实验室电源:拆解恒流源电路在5个真实产品中的应用
  • 海景美女图FLUX.1参数详解:引导强度3.5为何最优?随机种子-1的生成逻辑揭秘
  • samba服务器的安装
  • GitHub汉化插件终极指南:5分钟打造全中文开发环境
  • 终极指南:如何在Windows 10/11上快速安装开源Android子系统WSABuilds
  • GTE-Base-ZH与卷积神经网络结合:多模态内容理解初探
  • AIGlasses_for_navigation开发环境配置:Node.js安装及后端服务框架搭建
  • 2026年揭秘!日照那些让你放心吃海鲜,绝不宰客的宝藏店铺
  • OpenClaw 新手部署教程:WSL2 静默自启 + Windows 浏览器访问
  • 3D游戏开发实战:Unity中快速计算点到直线距离的两种高效方法
  • 昨天还在说没对象,今天工作都没了。 那我有什么?有房贷啊,还有一身过劳的臭毛病
  • ClawdBot惊艳效果:模糊车牌图片→OCR识别→中英双语翻译+校验
  • AI论文写作哪个好?2026年精选6款AI写论文软件排行榜,AI率精准控制无压力!
  • Defender Control:彻底掌控Windows安全防护的3种实用方法
  • CUDA driver error: invalid argument问题修改
  • ChatGLM-6B GPU资源监控教程:nvidia-smi实时观测显存与计算利用率
  • 终极指南:5步掌握Blender与ZBrush无缝桥接插件GoB的完整安装与使用教程
  • 3分钟搞定!Windows 11任务栏拖放功能一键修复指南 [特殊字符]
  • Topit:重塑数字注意力流,Mac端智能视觉层管理终极方案
  • 如何高效备份微信聊天记录:5个实用技巧指南
  • AIGlasses_for_navigation惊艳效果:便利店货架中红牛与AD钙奶并排摆放识别特写
  • 告别重复点击疲劳:MouseClick鼠标连点器完整指南
  • MedGemma医疗助手使用指南:如何提问才能获得更专业的医学建议?
  • 告别地理数据处理烦恼:Mapshaper开源工具的终极解决方案
  • USB安全弹出神器:告别“设备正在使用“烦恼的终极解决方案
  • 如何快速掌握BlenderKit:3个简单秘诀让你成为3D创作高手
  • Wan2.1-umt5开发环境搭建:从操作系统重装到Anaconda环境配置全流程
  • 抖音内容批量下载神器:零基础也能轻松掌握的免费工具
  • 南北阁Nanbeige 4.1-3B固件开发实战:从编译到烧录全流程
  • 从SQL注入到Linux提权:DC-3靶场渗透实战中的5个关键转折点解析