最好的权限设计,是先区分功能权限和数据权限
本文为我们介绍了功能权限和数据权限的不同点、以及不同部分中的要点与注意事项。
做2B的系统总是不可回避的遇上权限问题,他不是核心业务却又必不可少,而且总是牵一发而动全身,更要命的是不同客户组织架构完全不同,功能复用性很低。有没有什么方法论能快速理清权限问题呢?
我们一般说【权限】的时候是在说功能权限和数据权限。功能权限指用户登录系统后能看到什么模块,能看到哪些页面,而数据权限指的是用户在某个模块里能看到几条数据,能看到哪些数据。以下分别描述一下我对功能权限和数据权限的理解。
功能权限
在企业系统中,通过配置用户的功能权限可以解决不同的人分管不同业务的需求,但是如何实现快速配置?功能的粒度是模块级的还是页面级的还是更细粒度的?跨模块操作时没权限怎么办?
图1-1
RBAC模型
说到功能权限不得不说RBAC(Role Based Access Control)模型,它的中文是基于角色的访问控制,主要是将功能组合成角色,再将角色分配给用户,也就是说 角色是功能的合集 。RBAC有多个成员,但是基础的RBAC0就足够我们涉及的系统使用了。(如果想了解更多,请点击RBAC权限管理总结)
为什么要引入这个模型呢?请看以下的例子:
企业A一共有12个功能,需要创建100个用户,这些用户中有管财务的、有管人事的、有管销售的等等。如果不引入RBAC模型,我们需要每创建一个用户就要分配一次功能,至少(每个用户只有一个功能)操作100次,如果人数增加到1000甚至10000,并且一个用户可能会有多个功能的时候,操作会非常繁琐,如图:
图1-2
经过多次操作发现:分配给某些人的功能都是相同的,比如分配给A、B等10个用户的功能都是客户管理、订单管理及供应商管理这几个模块,那是不是可以把这几个功能模块打成一个包整体分给需要的用户呢?
这个包就叫做角色。由于角色和功能的对应关系相对固定,给用户分配权限的时候只分配角色即可。
图1-3
所以引入RBAC模型的意义在于:
- 解耦用户和功能,降低操作错误率;
- 降低功能权限分配的繁琐程度。
图1-4 图中一个用户对应一个角色,但实际场景中也可以是一个用户对应多个角色
有些更复杂的系统可能会涉及RBAC家族的其他成员:RBAC1、RBAC3、RBAC97等,并逐渐看到【用户组】、【角色继承】、【受限角色】等概念,但模型的引入只是多了依据和调理,复杂度并不会因为模型的增多而快速降低,模型引入带来的边际效用只会越来越低。
更多角色问题请参考:角色权限设计的100种解法
功能的粒度
功能越多,操作越繁琐,复杂度越高,所以选择合适的功能粒度才能快速理清权限问题,也能帮助用户提升工作效率。
功能的粒度从粗到细一般分为:模块级->页面级->接口级(接口级的功能权限指的是哪个角色能调用哪些接口)。
从后台角度:为了系统安全,代码肯定都会实现到级口级。那我们做粒度选择的意义是什么?当然是为用户降本增效。只是粒度越粗,用户操作越简单,灵活性却越低。
非技术类的网站做到模块级就够了,否则用户体验会让人欲哭无泪。对比以下两张图感受一下:
图1-5
功能的优先级
如果权限必须细化到页面甚至接口级别应该要遵循一个优先级规律,即只要分配低优先级的功能必须先分配高优先级的功能,否则会出现有删除权限却找不到操作位置的尴尬情况(删除按钮在列表页面,却没有分配查看列表页面的权限)。具体做法可以通过交互的方式解决,比如检测到勾选低优先级的功能就自动帮助勾选高优先级的,或者通过提示性的文字帮助用户组合勾选。
需要说明的是不同的交互设计会导致优先级不一样,因为有的按钮会放在列表,有的按钮只放在详情页。我们常用的优先级顺序是查看详情>查看列表>增加、删除、编辑、其他操作按钮。
跨模块访问的问题
有一个功能权限是模块级的系统,其中模块A的页面有访问模块B某个页面的链接,那么只有模块A权限的用户可以点击链接进入模块B吗?
这个问题有两种解法:
1. 允许只有模块A权限的人通过链接访问模块B
这说明系统有一条隐含的规则:能看到链接就表示用户由模块A和模块B的某些页面的功能权限。后台需要给所有【有模块A权限】的用户【自动分配】访问模块B某个页面的权限。
2. 只有既有模块A权限也有模块B权限的用户才可以通过链接进行访问
这说明这个链接就是给同时拥有两个模块权限的用户设计的。即只有模块A权限的用户不能通过链接访问模块B。
这儿就需要根据真实业务替用户选择一种方式,但不管那种方式都可以通过交互和预定义的方式让操作更简便,比如如果选择第1种解法,那么初始化一个有A模块权限和B模块某个页面的角色,让用户随时可以选择。
数据权限
如果所有信息都是公开透明的,也就不需要做数据权限的控制。可现实世界如此复杂,每个人需要看到的、应该看到的数据永远不同,数据权限便应这些需要和规则而生。
数据权限解决的是用户能看到多少数据量和什么数据的问题,例如A和B两个用户都能看到销售模块,但A能看到320条数据,B只能看到100条数据,且A能看到的320条数据中包含着B能看到的100条数据,这些都是由数据权限决定的。
数据权限和什么有关?
数据权限一般和企业的组织架构相关,而组织架构分为树状和扁平状的(还有更复杂组织架构,此处暂不做说明)
图2-1 树状组织架构,每个部门都是一个结点
图2-2 扁平状组织架构
因为扁平状组织架构较为简单,需要注意的问题已经隐含在树状架构中,所以以下主要讲树状架构。
层级数量
不同的企业层级深度不同,如果系统支持无限层级,那好处是通用,坏处是带来了数据的复杂性和视觉实现的复杂性,所以也要具体问题具体分析。
结点间的数据共享方式
图2-3
因为用户具有的权限是功能权限和数据权限交叉定义的,所以此处假设G、A、B部门的用户都被赋予了用户管理和资产管理的功能权限
目前结点间的数据共享方式有几类:
- 父结点可以管理所有子结点的数据:用户G可以【管理】部门A、部门B的所有用户和所有资产。
- 子结点可以管理父结点的数据:用户A1可以【管理】部门G的所有用户和所有资产。
- 兄弟结点之间可以互相管理:用户A1可以【管理】部门B的所有用户和所有资产。
- 结点只能管理自己所在结点的数据:用户A1只能【管理】部门A的所有用户和所有资产。
- 结点里的用户只能看到自己的数据:用户A1只能【管理】用户A1自己创建的用户和资产。
实际业务系统进行数据权限的定义时:
a. 选择以上一种或几种规则;
b. 根据业务而定定义以上的【管理】:增、删、改、查及各种小功能的组合。
比如如果选择父结点只能【查看而不能编辑、删除、新增】子结点的所有数据,那么图中用户G只能查看部门A的所有数据而不能对其进行编辑、删除和新增。
结点里的用户存在上下级关系怎么办?
图2-4 和图2-3一样
如果实际业务中用户A1是用户A2的上级,并要求用户A1能看用户A2的数据,而用户A2不能看用户A1的数据怎么办?
如果数据权限只规定到结点级(组织级),那么用户A1和用户A2看到的数据都是一样的。所有需要再次引入功能权限的【角色】解决这个人员上下级问题。
例如,如图2-4,系统选择的结点间的数据共享方式是:结点只能增删改查自己所在结点的数据,另外引入角色规则:管理员可以增删改查所在结点所有数据,非管理员只能删改查自己创建的数据。那么 如果用户A1的角色是管理员,A2是非管理员,A1就能增删改查A部门所有资产,A2只能查看、编辑、删除自己创建的资产。
扁平架构
扁平化的组织架构比较简单,只存在树状架构中的第3个问题。请参考树状架构的第3个问题。
功能权限和数据权限的碰撞:跨模块的数据【使用】问题
假设某系统一共有两个模块:型号管理和设备管理,操作系统的流程是先创建型号再创建设备,如果一个用户只有设备管理而没有型号管理的权限,在创建设备时是否可以选型号?
图2-5
这其实是一个功能权限(接口级)和数据权限融合的问题,即用户创建设备的时候是否有请求型号列表接口的权限?列表中要展示哪些数据?
从功能权限讲: 用户肯定有请求接口列表的权限,否则流程就无法走通了。
从数据权限讲: 有几种规则作为参考,具体根据实际业务进行选择:
- 不管哪个层级或者谁创建的型号都在接口中展示(即型号数据在别的模块使用时全局可见);
- 只展示当前登录用户所属结点创建的型号;
- 只展示当前登录用户所属结点及下属节点创建的型号(扁平化组织架构不适用);
- 只展示当前登录用户所属结点的父结点创建的型号(扁平化组织架构不适用);
- 只展示当前登录用户所属结点的兄弟结点创建的型号(扁平化组织架构不适用);
- 只展示当前登录用户创建的型号。
总结
- 建设toB的系统时要考虑两种权限:功能权限和数据权限。
- 功能权限可以参考RBAC模型,通过引入角色、用户组等概念降低复杂度。但系统用户数量庞大,功能极度复杂且粒度足够细时,复杂度已不可避免,只需考虑是把复杂交给用户、运维还是代码。
- 数据权限主要和组织架构有关,组织脚骨中树状架构较为复杂,需要统一或者分模块的定义层级间数据共享问题。数据权限定义过程中如果出现同一结点下的【用户间层级问题(上下级)】需要回到功能权限的【角色定义】去解决。
- 有一类跨模块【使用数据】的问题也可以看成既定的接口权限和可选的数据权限问题。
总之扬帆在角色权限的海洋里绕啊绕啊绕,总会绕出几个原则,走出几个理论让我们绕的更快,徜徉的更有成就感。
本文由 @娜娜 原创发布于人人都是产品经理,未经许可,禁止转载。
题图来自Unsplash,基于CC0协议
作者暂无likerid, 赞赏暂由本网站代持,当作者有likerid后会全部转账给作者(我们会尽力而为)。Tips: Until now, everytime you want to store your article, we will help you store it in Filecoin network. In the future, you can store it in Filecoin network using your own filecoin.
Support author:
Author's Filecoin address:
Or you can use Likecoin to support author: