若依笔记(三):权限控制与数据隔离

目录

数据隔离/权限控制

用户/权限/部门/岗位

​数据隔离

mybatis的maaper写法

注解和切面

前端路由拦截


已知若依单体的前端采用vue-element-admin,在前端的专栏系列vue-element-admin的动态路由已详细拆解,其最大特点是使用后端返回数据控制前端菜单,每次接口请求前会有路由拦截来获取权限和菜单列表并重新渲染页面,配合若依后端自己实现的数据权限切面,能够实现很好地的数据隔离和权限隔离,那么现在就从代码层面分析其实现;

数据隔离/权限控制

若依系统的权限控制实体分为目录-->菜单-->按钮,最小到按钮级别,也就是针对某个表可以控制其是否能够删除或新增,普通用户只能查看筛选(查);

  • 目录:左侧菜单栏
  • 菜单:耳机菜单
  • 按钮:数据的增删改查操作

用户/权限/部门/岗位

权限控制主体是用户,用户具有角色、部门、岗位的细分属性,

  • 角色:角色可以控制菜单,角色意味着该用户具备哪些数据的管理操作权限,可以在角色编辑栏针对角色来控制不同的菜单项;
  • 部门:部门不涉及权限,但涉及组织架构,当树形展开部门组织架构后,可以清晰明了地知道用户隶属于什么部门,及其岗位是啥,只是用户的某个属性;
  • 岗位:岗位也只是用户的某个属性,岗位与角色关联,比如测试组的负责人应该可以查看所有测试表的数据,那么可以给这个负责人用户1个test-admin角色,给其测试表的所有操作权限,同理,研发和营销人员都应该有1个对应的admin角色,通过角色控制对应部门的菜单列表;

刚才说可以通过定义角色权限来控制目录+菜单,实现不同的部门看不同的菜单栏,那么如果同一个部门内部,比如营销人员A和营销人员B,A是小组长可以新增任务,B只能查看和认领/修改,那么这就涉及同一个表的按钮级别权限,可以新建一个营销的comon角色,该角色只能查看按钮;

 数据隔离

上面从功能层面描述了权限管理体系,也就是实现从前端去控制用户的操作权限,那么后端的数据如何做到数据隔离呢?数据隔离就是不同部门看隶属于其部门的数据,部门A和部门B的common普通用户都有查看<施工监测>这个目录--->菜单的权限,并且均有查看权限,那么其查看的数据应该是跟部门绑定的,这就是通过后端切面来实现的;

mybatis的maaper写法

我们来看代码生成器生成的mapper怎么写的,sql的where循环条件最后一行有params.dataScope的这个字符串,它是入参ProjectJklc这个pojo类的某个属性,这里可以把他当作1个占位符;

    <select id="selectProjectJklcList" parameterType="ProjectJklc" resultMap="ProjectJklcResult"><include refid="selectProjectJklcVo"/><where>  <if test="gdxc != null "> and gdxc = #{gdxc}</if><if test="zbsl != null "> and zbsl = #{zbsl}</if><if test="gjxc != null "> and gjxc = #{gjxc}</if><if test="scyl != null "> and scyl = #{scyl}</if><if test="cjyl != null "> and cjyl = #{cjyl}</if><if test="gjnl != null "> and gjnl = #{gjnl}</if><if test="tnl != null "> and tnl = #{tnl}</if><if test="mgzl != null "> and mgzl = #{mgzl}</if><if test="wynbwy != null "> and wynbwy = #{wynbwy}</if><if test="xgjy != null  and xgjy != ''"> and xgjy = #{xgjy}</if>${params.dataScope}</where></select>

在 ProjectJklc这个实体定义中继承了BaseEntity,它有params属性,是个map默认是空;

public class ProjectJklc extends BaseEntity
private Map<String, Object> params;

 params在何时被填充的,这个sql何时被补充完整的?可以查看使用这个mapper的impl调用入口,有个注解@DataScope(deptAlias = "project_jklc"),这个注解中定义了deptAlias这个key,翻译过来是部门表别名,意味着这个value是个跨部门访问的表;

    /*** 查询监控量测列表* * @param projectJklc 监控量测* @return 监控量测*/@Override@DataScope(deptAlias = "project_jklc")public List<ProjectJklc> selectProjectJklcList(ProjectJklc projectJklc){return projectJklcMapper.selectProjectJklcList(projectJklc);}
注解和切面

@DataScope注解定义有3个属性,部门表别名,用户表别名,权限字符,实现跨部门跨用户的数据隔离过滤条件;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope
{/*** 部门表的别名*/public String deptAlias() default "";/*** 用户表的别名*/public String userAlias() default "";/*** 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来*/public String permission() default "";
}

在DataScopeAspect切面中有一系列判断,其核心是首先看当前用户所属权限是否限制了本人操作过的数据只有本人能看,或部门内都可以使用,比如当前用户所属角色(营销人员B的营销common角色)若是仅仅本人数据权限就只能查user_id等于她自己的;

判断中角色如果是全部数据权限/all权限不拼接sql,正常情况是本部门可以访问,也就是只做部门间的数据隔离,那么就只拼接dept_id的SQL语句,如下:

            if (DATA_SCOPE_ALL.equals(dataScope)){sqlString = new StringBuilder();conditions.add(dataScope);break;}else if (DATA_SCOPE_DEPT.equals(dataScope)){sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));}

该切面在方法调用前填充了实体中的params属性,在mybaits的mapper使用时候这个实体已经有值了,这样就实现了部门/用户层面的数据隔离。

前端路由拦截

那么代码生成器生成的前端代码如何配合后端来完成按钮级别的控制的呢?这个就涉及到前端代码入侵,在前端<el-button>按钮组件上有个v-hasPermi属性

      <el-col :span="1.5"><el-buttontype="danger"plainicon="el-icon-delete"size="mini":disabled="multiple"@click="handleDelete"v-hasPermi="['system:jklc:remove']">删除</el-button></el-col>

v-hasPermi是自定义指令,用于处理操作权限。它通过获取store中的permissions来判断用户是否有操作权限,如果没有则移除该元素,[system:jklc:query]将被解析成system,jklc,query然后比对permission获取的后端权限list,如果没有比对上,就是fasle,就不会选自然这个el-button组件。

import store from '@/store'export default {inserted(el, binding, vnode) {const { value } = bindingconst all_permission = "*:*:*";const permissions = store.getters && store.getters.permissionsif (value && value instanceof Array && value.length > 0) {const permissionFlag = valueconst hasPermissions = permissions.some(permission => {return all_permission === permission || permissionFlag.includes(permission)})if (!hasPermissions) {el.parentNode && el.parentNode.removeChild(el)}} else {throw new Error(`请设置操作权限标签值`)}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/128702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工业级环网交换机如何使用

工业级环网交换机是用于工业环境中的网络通信设备&#xff0c;具有高可靠性、耐用性和适应恶劣环境的特点。下面是一般的使用步骤&#xff1a; 1. 确保交换机的电源供应稳定并连接好电源线。 2. 将需要连接的网络设备&#xff08;如计算机、服务器、传感器等&#xff09;通过以…

ssh远程登录服务

目录 1.1版本协商阶段 1.2密钥和算法协商阶段 1.3认证阶段(两种认证方法): 2.1.安装ssh 2.2.配置文件分析: 3.1配置ssh监听端口号 3.2拒绝以root身份登录服务器 3.3虚拟机之间实现免密登录 3.4xshell免密登录 SSH (Secure Shell Protocol,安全壳程序协议)由IETF的网络…

模电学习路径

交流通路实质 列出电路方程1&#xff0c;方程1对时刻t做微分 所得方程1‘ 即为 交流通路 方程1对时刻t做微分&#xff1a;两个不同时刻的方程1相减&#xff0c;并 令两时刻差为 无穷小 微分 改成 差 模电学习路径&#xff1a; 理论 《电路原理》清华大学 于歆杰 朱桂萍 陆文…

【向生活低头】win7打印机共享给win11使用,win11无法连接问题的解决

打印机是跟win7的电脑连接的&#xff0c;然后试了很多方法&#xff0c;win11都没法添加该打印机去使用。 网上的方法乱七八糟啥都有&#xff0c;但试了以后&#xff0c;发现基本没什么用。 刚刚发现知乎上的一个回答是有用的&#xff0c;这里做记录以备后用。 1.打开控制面板的…

修复国产电脑麒麟系统开机出现initramfs 问题

目录预览 一、问题描述二、原因分析三、解决方案四、知识点呀initramfsBusyBox 五、参考链接 一、问题描述 国产麒麟系统出现 initramfs 模式 二、原因分析 一般在拷贝卡顿过程【强制关机】或者电【脑异常断电】的情况下概率性导致系统分区损坏&#xff0c;重启后大概率就会进…

数字孪生技术:金融业合规与自动化的未来

在当今数字化时代&#xff0c;金融行业正积极探索数字孪生技术&#xff0c;以实现更高效的运营和更好的客户体验。数字孪生是一种将实体世界的对象、过程和系统数字化为虚拟模型的技术&#xff0c;金融机构正在充分利用它带来的众多优势。 1. 风险管理与模拟 数字孪生模型可用…

解决ECharts柱形图自定义单个柱子颜色图例无法显示

legend里data和series里的name需要对应series里对象需要设置stack属性&#xff0c;属性值都一样即可显示单柱重点在于series里对象data属性设置&#xff0c;必须使用&#xff0c;否则影响柱体上数值显示tooltip的值需要自定义&#xff0c;否则会显示堆叠柱状图的tooltip格式&am…

Linux解决nvcc -V出现的-bash: nvcc command not found问题

两种解决办法&#xff1a; 1、第一种直接在bashrc文件中添加本地cuda路径&#xff1a; vim ~/.bashrc 定位到内容末尾&#xff0c;最末尾 添加命令&#xff1a; export LD_LIBRARY_PATH/usr/local/cuda/lib export PATH$PATH:/usr/local/cuda/bin添加后激活 source ~/.bashrc…

2023年【R1快开门式压力容器操作】试题及解析及R1快开门式压力容器操作模拟试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年【R1快开门式压力容器操作】试题及解析及R1快开门式压力容器操作模拟试题&#xff0c;包含R1快开门式压力容器操作试题及解析答案和解析及R1快开门式压力容器操作模拟试题练习。安全生产模拟考试一点通结合国家…

论文 辅助笔记:t2vec train.py

1 train 1.1 加载training和validation数据 def train(args):logging.basicConfig(filenameos.path.join(args.data, "training.log"), levellogging.INFO)设置了日志的基本配置。将日志信息保存到名为 "training.log" 的文件中日志的级别被设置为 INFO&…

iZotope Ozone 11 Advanced for mac(臭氧11)11.0.0激活版

iZotope Ozone 11是一款功能丰富的母带处理工具&#xff0c;也是混音师和母带工程师工作中必备的工具之一。它能够满足母带的全部流程&#xff0c;包括均衡器&#xff08;EQ&#xff09;、压缩器&#xff08;Comp&#xff09;、限制器&#xff08;Limiter&#xff09;、多段宽度…

Vue3 实现 clipboard 复制功能

一个很小的交互功能&#xff0c;网上搜了一下有一个 vue3-clipboard 直接支持vue3&#xff0c;到github仓库看了下&#xff0c;原作者已经不维护这个项目了&#xff1a; 推荐使用 vueuse 自带的 useclipboard 功能&#xff0c;由 vue 团队维护&#xff0c;稳定性基本没问题 官…

十六章反射与注解总结

16.1 反射 反射&#xff08;Reflection&#xff09;是指在运行时获取类的信息&#xff0c;并可以动态调用类的方法、访问或修改类的属性&#xff0c;以及构造对象的能力。 Java的反射提供了一套API&#xff0c;允许你在运行时检查类的结构、调用类的方法、获取和设置类的属性&…

学习笔记三十三:准入控制

ResourceQuota准入控制器 ResourceQuota准入控制器限制cpu、内存、pod、deployment数量限制存储空间大小 LimitRanger准入控制器在limit名称空间创建pod&#xff0c;不指定资源&#xff0c;看看是否会被limitrange规则自动附加其资源限制创建pod&#xff0c;指定cpu请求是100m&…

Xcode15 模拟器 Rosetta 模式

打开Xcode15的方式其实没有Rosetta 选项了&#xff0c;但是可以跑Xcode默认Rosetta 模拟器。在xcode中如下方式打开&#xff1a; Product -> Destination -> Destination Architectures -> 打开Show Rosetta Destinations 然后用这些带Rosetta的模拟器运行&#xff1…

《研发效能(DevOps)工程师》课程简介(二)丨IDCF

为贯彻落实《关于深化人才发展体制机制改革的意见》&#xff0c;推动实施人才强国战略&#xff0c;促进专业技术人员提升职业素养、补充新知识新技能&#xff0c;实现人力资源深度开发&#xff0c;推动经济社会全面发展&#xff0c;根据《中华人民共和国劳动法》有关规定&#…

vivado 报错之procedural assignment to a non-register result is not permitted“

文章目录 这个错误通常是由于尝试在非寄存器类型的对象上进行过程赋值所引起的。在 Verilog 中&#xff0c;当使用 always 块时&#xff0c;其中的赋值操作应该只用于寄存器类型的变量&#xff0c;比如 reg 类型。非寄存器类型的信号&#xff08;比如 wire&#xff09;不能在 a…

黑色星期五来袭,Ozon为你提供丰富的推广工具和资源,助你实现销售突破!

Ozon的“黑色星期五”促销活动为卖家们提供了丰富的推广工具和资源&#xff0c;以确保他们的商品在促销期间获得最大的曝光度和销售额。卖家们应该充分利用这些机会&#xff0c;制定合适的折扣策略&#xff0c;并确保他们的商品在Ozon平台上脱颖而出。 为了推广Ozon黑色星期五促…

C++归并排序算法的应用:计算右侧小于当前元素的个数

题目 给你一个整数数组 nums &#xff0c;按要求返回一个新数组 counts 。数组 counts 有该性质&#xff1a; counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。 示例 1&#xff1a; 输入&#xff1a;nums [5,2,6,1] 输出&#xff1a;[2,1,1,0] 解释&#xff1a; 5 …

深入理解TCP协议

深入理解TCP 1.TCP基础概念了解 1.1简介 TCP&#xff08;Transmission Control Protocol&#xff09;是一种计算机网络协议&#xff0c;用于在网络上可靠地传输数据。它确保数据的完整性、顺序性和可靠性&#xff0c;通过建立连接、数据分段、错误检测和恢复机制&#xff0c…