精确权限控制实现方法
阅读之前请先《理解Enhancer变量体系》。 关于如何实现不同用户角色访问不同的页面,请参考快速上手中《创建角色并授权》。 本章节介绍在同一页面中如何实现不同用户对数据的读写权限控制。
数据读取权限控制
在数据源配置中,可以使用当前登录用户相关的变量(用户ID,角色,所在部门...)作为查询条件,实现对查询结果的过滤。
例如实现
用户只能查看自己的订单
这一需求,SQL 条件形式上如下:SELECT ... FROM order o, order_items oi WHERE o.id = oi.order_id AND o.user_id = @USER_ID@ -- <-- 设置与用户 ID 相关的过滤条件
再例如实现
作为班主任的当前用户,只能查看本班学生的详细信息
这一需求,SQL 条件形式上如下:SELECT ... FROM student s, classInfo c WHERE c.master_id = @USER_ID@ -- <-- 设置条件只选择当前用户作为班主任的班级名单。 AND c.id = s.class_id -- <-- 根据班级 ID 连接查询出 student 信息。
又例如,部门总监只能查看本部门当月采购情况,SQL 条件形式上如下:
SELECT SUM(amount) amt, type FROM purchasing_records pr WHERE pr.deperatment_id = @USER_DEP_ID@ -- <-- 携带当前登录用户所在部门 ID 作为过滤条件。 AND ... GROUP BY type
数据写入权限控制
写入权限控制实现方法也是将当前用户及相关变量作为条件,以过滤越权操作。
例如实现
用户只能修改自己的订单地址
这一需求, SQL 条件形式上如下:UPDATE order SET address = @12-ADDRESS@ WHERE order.id = @12-ORDER_ID@ -- <-- 有 order_id 做精确更新的基础上 AND order.user_id = @USER_ID@ -- <-- 还需要携带用户 ID条件,避免非法操作。
再例如,
部门主管只能禁用本部门员工账号
这一需求,SQL 条件形式上如下:UPDATE userinfo u SET available = false WHERE u.id = @11-USER_ID@ AND u.department_id = @USER_DEP_ID@ -- <-- 补充当前用户所在部门条件,避免非法操作。
此外,对于跨系统鉴权实现,可以在【事件后台响应过程】中设置【SQL执行前后台脚本】完成相关跨系统接口调用逻辑。完毕之后调用 done 方法即可,详情参考 《掌握事件动作前后台响应机制》。
【补充说明 1】如果要实现列权限控制,即不同【角色】查看或者操作同一张表的不同字段,则需要为不同的角色分别创建不同的页面,独立完成各自逻辑,属于页面访问权限控制范畴。Enhancer 提供了页面复制功能,可以非常快速便捷的复用相似逻辑。
【补充说明 2】与用户相关的数据,除了登录所需要的 USER_ID,ROLES之外,其他信息可以存放在登录用户表中,用户登录时,系统会读取表字段名作为该用户相关的变量,供开发使用。
【补充说明 3】
SQL 过滤条件中使用的与当前用户相关的变量,需要使用不带数字的服务器端变量如 USER_ID, ROLES, DEPARTMENT, 而非前端变量 1-USER_ID, 1-ROLES, 1-DEPARTMENT。因为服务器端变量取自服务器端的 SESSION,不经过网络传递,不可伪造;而前端变量从浏览器传至服务器,可以被伪造。