必威体育Betway必威体育官网
当前位置:首页 > IT技术

实现数据权限控制的一种方法

时间:2019-08-19 20:42:07来源:IT技术作者:seo实验室小编阅读:61次「手机版」
 

权限控制

企业管理系统中,常常有这样的要求: 

1. 用户一般只能查看自己部门的数据 

2. 可以设置用户可以查看哪些部门的数据 

这种权限的控制,一般称为数据权限,与之对应的功能权限,则是系统中哪些功能可以使用——①菜单、按钮等元素能正常显示;②如果用户访问了本身不可见的功能,系统也能阻止(访问控制)。

开发时间长了,就发现编程一般就是两个问题: 

1. 在哪里设置(数据从哪里来) 

2. 在哪里使用(数据到哪里去) 

比如工作流引擎,设置,即在界面上拖画流程图,并保存为特定的xml数据;使用,即流程引擎解读xml数据,使其正确的按照用户的意图执行程序。 

数据权限的问题,同样可以分成这两个问题来处理。

设置的问题: 

在用户设置界面,设置用户的管辖权限

image

做到这样的设置界面,并不困难。

在这里,主要要解决的一个问题是,如何把这种关系存储下来 

常规方案:使用关联表[用户ID,组织ID] 

可是发现,一旦组织机构数量多了以后(如省市县乡,一般一个省就有1000个乡/街道以上),再加上用户数量多了以后——往往是组织机构节点越多,则用户也越多。理论上,这个关联表的数据量将到达千万级(仅理论上,因为对于绝大多数用户来说,仅能访问本部门数据)。

创新方案:组织机构使用code做主键,并且在用户表中新建字段为“已授权的组织(authorized_orgs)”,直接使用字符串逗号分隔的方式将该关系存起来。 

可是马上会发现,这个字段会很长很长,一个4级的组织,一般需要8位长的代码,如果选中的全部数据,按1000个单位来算,就会有9000长度(含逗号)的字符串。 

这里有一个取巧的办法,对于全选了数据,只保存上级单位的code,下级单位就不保存了——因为选中了上级就必然下级全部选上了。

该办法要求上下级代码存在一种明显的关系,如上级代码为 0100,下级代码0101。 

这个取巧的办法,理论上依然不能规避很长的组织机构代码(如选的全部是叶子节点数据),但在实践中,却是很好的办法——应该很少出现全部只选叶子节点,而不选父级节点的。 

使用ztree(js的树)的代码,可以这样写

复制代码

if(zTree==null){ 
         return; 
     } 
     var nodes = zTree.getNodes(); 
     var arr = []; 
     for(var i=0; i<nodes.length; i++){ 
         pushToArray(arr, nodes[i]); 
     } 
     console.log(arr.join(",")); 
     obj.authorizedOrgs = arr.join(","); 

function pushToArray(arr, node){ 
    if(!node.checked){ 
        return; 
    } 
    if(node.check_Child_State==2||node.check_Child_State==-1){//是节点完全选上(即不是半选状态)或叶子节点,直接添加 
        arr.push(node.code); 
    }else if(node.check_Child_State==1){//节点半选状态,递归往下找完全选中状态的 
        for(var i=0; i<node.children.length; i++){ 
            pushToArray(arr, node.children[i]); 
        }    
    } 
}

复制代码

-----分割线:以上解决怎么设置的问题,以下讨论怎么解决使用的问题--------

数据权限控制的基本思路,一般是会执行的sql语句中添加where条件,以便限定查出的数据, 

如 where 所属机构 in (用户可访问的机构) 

而不是在数据查询出来之后,再到代码中进行过滤——因为一般都会对数据进行高效分页,如果已经查询出来数据,再在代码中进行过滤的话,就可能出现一页数据不足一页的情况,数据总数也会与实际页面上查出的数据行不一致。

第一步,在需要进行过滤的表中,要添加一个字段,如org_code,标明每条记录所属的组织机构。 

第二步,在查询语句中加入过滤条件。 

我们要加入的SQL语句,大概如下: 

where 所属机构 in ('ZZ0101', 'ZZ0102',...) 

假如我们前面存的代码是'ZZ0100,ZZ0201',其中存的是其父级节点'ZZ0100',代表了 'ZZ0101', 'ZZ0102', ... 

所以要写成 

where ((所属机构 like 'ZZ01%') or (所属机构='ZZ0201')) 

拼凑这样的SQL语句估计也是比较麻烦的一件事,有没有简便一点的方法呢?答案是有。 

经查,oracle,sqlserver,mysql都是支持正则式查询的。 

这样,我们可以把'ZZ0100,ZZ0201'变成一个正则式,放入条件中进行查询即可! 

变成正则式就是 '(^ZZ01.*)|(^ZZ0201)',在mysql使用正则式查询,就是 where 所属机构 RLIKE '(^ZZ01.*)|(^ZZ0201)' 

变成正则式之后,也便于放入session中进行存储。 

什么,你的数据库支持正则式,orm不支持正则式,那还用orm做什么

相关阅读

四款常见数据库比较同步软件汇总

下载网站:www.SyncNavigator.CN  客服QQ1793040 ----------------------------------------------------------   关于HKR

css3实现 slideUp/slideDown效果

1. 纯css3实现<h1><mark>PURE CSS</mark> Slide Up and Slide Down</h1> <input id="toggle" type="checkbox"><label for="toggl

DDL(数据库定义语言)

DDL(Data Definition Language) 数据定义语言 1. 基本操作 查看所有数据库名称:【语法:show databases;】 切换数据库:【语法:use

LSP劫持与网络数据转发代理服务器的心得笔记

前言 本文的目标读者是那些对LSP劫持有一定了解,也写了一些lsp程序,并想进一步深研lsp,意图做LSP代理工具的人。 如果读者对LSP没有

何为fine-tune以及其一般的实现流程

第一问:Finetune:是微调的意思,也就是整个要训练的网络不是从随机状态开始训练而是从一个比较好的初始状态开始微调。第二问:1)使用预

分享到:

栏目导航

推荐阅读

热门阅读