在B端产品中,用户权限是非常重要且必需的功能,产品中每一个功能、每一个操作、每一个数据,产品经理都要思考清楚哪些用户具有相应的权限。
RBAC(Role-Based Access Control)模型是一种基于角色的权限管理模型。
角色的定义:拥有相同权限的用户的身份标签。
由简单到复杂又可以分为RBAC-0、RBAC-1、RBAC-2、RBAC-3四大模型。

RBAC四大模型

RBAC-0

RBAC-0是最基础、最简单的一种模型,前一小节中举的例子就属于这种模型。用户与角色、角色与权限间建立关联,每种对应关系均为多对多,即一个用户可以有多个角色,一个角色可以有多个权限。
当用户有多种角色时,那么就会拥有这些角色所有权限的并集,在实际应用中,要注意某两个角色部分权限冲突的情况,这时需要根据业务需求定义清楚,以免开发人员犯迷糊。
image.png

RBAC-1

RBAC-1是在RBAC-0的基础上,增加了继承关系,包括角色继承和范围继承两种。
(1)角色继承
角色继承是针对两个不同角色而言的,一个角色只能拥有另一角色的部分权限。这个角色的权限大小受另一角色权限的影响。如在HRM系统中有“人事总监”和“人事助理”两个角色,人事总监的权限包括“审批请假单和修改人员信息”,产品经理在定义人事助理的角色时,为了避免出现人事助理的权限大于人事总监的权限的情况,就要增加继承条件的约束,即人事助理的权限只能是人事总监的子集。
(2)范围继承
范围继承是指多个用户是同一个角色,但由于这些用户所在层级的差异,他们的操作权限虽然相同,但可查看的数据范围却不同。如在一个集团企业中,集团的人事部门不仅管理集团总部的人事方面的业务,还可管理下属所有子公司的人事方面的业务,虽然同样是人事总监,都可以添加人员信息,但子公司的人事总监只能添加本公司及其下属公司的人员信息,不能添加上级公司的人员信息,而集团的人事总监则可以添加集团和所有下级子公司的人员信息,这就是范围的继承。
角色继承示例
image.png
范围继承示例
image.png
范围继承相比于角色继承,是一种不需要引入新的角色,通过数据范围的控制,实现同一角色不同权限范围的方式,这样可以极大地简化系统的角色体系。

RBAC-2

有些场景中,如果用户、角色、权限完全自由,随意配置,会存在一定风险,如既是人事总监,又是部门管理者。为了避免某些人员角色过多,权限过大,我们在定义用户可拥有的角色时可以增加一些限制条件,如任何一位用户,“人事总监”与“部门管理者”两个角色只能二选一。
类似的限制条件根据业务需求还可以定义很多,我们将这种在用户、角色、权限间增加各种限制条件的权限模型叫作RBAC-2。
image.png

RBAC-3

RBAC-3是RBAC-1与RBAC-2的结合,即角色、权限既有继承关系,又有各类限制条件。不过这种模式的应用场景不多,无论是角色体系设计还是开发都比较复杂,维护和迭代成本也很高,所以要慎重使用。

单系统的用户权限

设计单个系统的用户权限设计是指将与业务相关的功能和用户权限设置在同一个系统中的设计。当公司的各种系统不多时,我们一般会采用这种方式,将用户、角色、权限、业务在同一个系统中统一管理起来。

1)用户管理

用户管理是将此系统所有使用用户进行统一管理的功能模块,但凡需要使用系统的用户,都需要先由管理员添加进系统才能使用。定制化阶段的产品,一般不需要做注册功能,管理员在系统中手动添加用户后,由系统默认或随机生成一个初始密码,用户在第一次使用时自己手动修改。所以这个功能模块就是用来管理用户的基本信息的。

2)角色管理

角色作为用户与权限的联结点,是无法独立存在的。
需要注意的是,在很多应用于公司日常管理的产品中,系统角色很容易与公司组织架构中的职位混为一谈,有的产品经理在设计角色体系时受此影响,强行把系统角色与公司职位保持一致,但其实这种强行一致是没有必要的。
在实际设计产品角色时,需要满足以下两项基本原则。

  • 定义清晰。每个角色应该清楚地定义其职责、权限,每次增加新功能时,都需要确定清楚新的变化对哪些角色有影响,影响是什么。对于调研阶段的角色分析可以不用满足这一要求,因为当时产品经理对业务理解不深,角色也不能完全确定,所以无法做到很清晰,但到了实际产品设计中,这些就要全部清晰地明确下来了。
  • 尽量简化。每增加一个新角色,产品设计和开发都要付出很高的成本,尤其是后期迭代的时候,很容易对现有的角色体系造成冲击,出现各种意想不到的问题,所以我们在设计时需要尽可能地简化角色体系。对于权限差异不大的角色,可以考虑合并或引入新的维度来简化,如前文提到的通过范围继承来简化角色。

【PS:既然角色这么不灵活,角色管理的意义也就不大了。】
根据用户获取角色的条件,可以将角色分为强角色和弱角色两类。
(1)强角色
强角色是指需要在系统中手动配置的角色。设为这类角色的用户需要先由管理员在系统中手动配置才能拥有这个角色,解除时也需要手动解除。
(2)弱角色
弱角色是指在系统中不需要手动配置,用户进行某项操作或被他人指派后自动所拥有的角色。当用户的操作或被他人的指派的相关操作完成后,这个角色就自动随之解除。例如,很多产品中定义的“游客”这一角色,用户只要登录系统,就会被自动赋予游客角色,用户退出系统后游客角色自动解除;在任务管理中,韩梅梅分配了一个任务给李雷,这时李雷就会被自动赋予“任务负责人”角色,就具有了对其负责的任务进行相关操作的权限,当李雷不再负责任何任务时,他身上的“任务负责人”角色就会自动解除。

3)权限管理

在我们日常讨论的权限中,权限可以分为数据权限和操作权限两类。
(1)数据权限
数据权限是指用户能否查看某些数据的权限,所以也称查看权限。系统里每个数据都要定义可查看的角色,大到一个菜单栏目,小到一个具体字段,都属于系统中的数据。
在定义角色的查看权限时,粒度要视业务需求而定,不过需要与产品的结构对应,不能出现数据位置模糊、权限相互矛盾的情况。例如,在说明“人事总监可以看到公司所有人的工资单,其他角色只能看到自己的工资单”这个权限时,就应该从一级菜单开始,按产品的结构,一层一层地指定数据路径,即XX角色具有XX菜单-XX栏目-XX数据的查看权限。
(2)操作权限
操作权限是指用户能否操作某些功能的权限,简单来说就是用户能否点击系统中的某个按钮或链接(打开页面也是点击链接的一种)。在定义操作权限时,需要与查看权限相关联。

  • 先有查看权限,才有操作权限。
  • 取消了查看权限,就自动取消了操作权限。
  • 当用户没有操作权限时,对应的操作按钮或链接最好隐藏,不要等到用户点击后才告诉他没有权限,即“可见即可用”。

【PS:可见即可用比置灰好】
4)灵活配置
在前面“角色管理”中我们说过,为了避免设计复杂和不必要的影响,要尽量减少角色的变动,但如果在实际业务中,确实存在角色或相关权限变动比较频繁的情况,这时就可以考虑将“角色管理”和“权限管理”合并为一个整体,设计成可通过页面灵活配置的功能。

多系统的用户权限设计

1)应用场景

多个系统的用户权限设计主要有以下两个应用场景。
场景一:多个子系统属于同一父系统,虽然这些子系统管理的业务内容不同,但它们可以共用一套完整的用户-角色-权限体系。
场景二:多个系统各自完全独立,每个系统的用户-角色-权限体系也完全独立,但这套体系中的部分内容可以共用。例如,公司内部使用的大多数系统都可以共用一套用户数据,而不需要各自维护。
无论是单系统的用户权限设计还是多系统的用户权限设计,都是围绕用户、角色、权限展开的,所以它们的理论基础是一样的,只是在面对多个系统时,如果每个系统都各自建一套完整的用户-角色-权限体系,对于可以共用的那部分来说,就是一种浪费,而且还会造成数据不同步的问题。

2)方案一:将共用部分独立为新系统

我们要分析在用户权限体系中,哪些数据是多个系统共用的,这里的多个系统不是指所有系统,而是只要超过三个系统可能共用,我们就可以考虑将这部分数据独立出来,单独进行管理。
(1)方案思路
以系统A、B为多个系统的代表来讲解设计思路。经过分析,系统A与系统B中的用户、组织数据是相同或绝大部分相同的,可以共用,这时我们就可以把用户、组织数据抽取出来,独立成一个新的【用户管理系统】,原来的系统A、B就只需要完成各自的业务功能、角色、权限就可以了,当系统A、B需要用到用户、组织数据时,则通过接口从用户管理系统中获取,这样就只需要维护一套数据,当用户信息有变动时,我们只改动户管理系统中的数据就够了。
image.png
用户数据是每个系统都要用到的,复用性很强,所以同样的思路,我们就可以把散落在各个系统中的用户数据都放到用户管理系统中,合并去重,将用户管理系统中的数据逐步完善成一个全集,然后通过标签、所属组织等维度对这些数据进行区分,各个系统通过接口调取数据时,接口会同时返回这些划分维度,各个系统根据需求选择子集数据就可以了。这样做的另一个好处是用户只需要通过用户管理系统管理自己的账号和密码,然后用统一的账号登录所有共用用户数据的系统,无须一个个地注册。
(2)方案问题
这种抽取也会产生其他问题。
问题一:抽取对象如何选择
有的可抽取对象是比较容易判断的,如用户数据;但有的对象则不那么明确,如角色,有的角色可能由十来个系统共用,如项目经理,而有的角色可能只有一个系统能用到,如人事总监,这时要不要把“角色”这一对象抽离出来,抽离出来如何管理,就需要根据需求场景好好思考了。
这里没有绝对的指标来明确共用程度达到多少就可以抽取,主要是看抽取这些对象节约的成本、带来的价值是否高于各自维护的成本。
问题二:独立系统越来越复杂
系统A、B的用户数据并非全部共用,而是部分共用,系统A、B各自还包含了少量个性化内容,这些个性化内容又与共用部分强关联,不可分割,所以为了同时满足系统A和系统B的需求,独立的用户管理系统就要把这些少量的个性化部分也管理起来。
当我们抽取的部分越多、想覆盖的业务场景越多,夹带的个性化内容就会越多。例如,我们现在抽取的用户数据不单单是用户的身份信息,还包括用户所属的组织、岗位等大量强相关信息,当公司组织、业务足够复杂时,一个公司就会出现多套组织树,在大型集团公司里,会同时存在产权树、法人树、业务管理树和其他各类组织树,这些组织树管理的用户是同一批人,但不同业务系统所需要的组织树却是不同的,这时用户管理系统就要同时把用户及这些组织树的关系都管理起来,以满足各个业务系统的需求。久而久之,用户管理系统就会越来越复杂,维护成本越来越高。
这个问题从根本上是无法避免的,因为这些工作用户管理系统不做,其他业务系统就要做,而且做起来更麻烦,所以我们真正能简化的方向是合理选择抽取的部分,并非抽取得越多越好。
问题三:风险集中
独立的用户管理系统作为公共服务,对每个关联系统都有影响,一旦出现问题,就可能导致所有关联系统都用不了,所以做公共服务系统的人员往往压力是最大的,每次发版都提心吊胆,出现问题就会招来一片骂声,要么不出事,要么出大事,是真正的“牵一发而动全身”。
这就是抽离公共服务最大的风险——风险都集中了。因此,一定要从技术上做好容灾备份、权限控制等措施。

3)方案二:共用部分合并到其中一个系统中

方案二的思路与方案一的思路是相似的,都是先分析可共用部分,然后解耦、合并,区别在于方案二不是将共用部分独立成新系统,而是将其合并到其中一个系统里,最常担此重任的就是我们现在做的HRM系统,因为这些数据本来就是从HRM系统录入、管理的。
image.png
虽然是将共用部分合并到了HRM系统中,但这些共用数据还是会被多方需求,因此还是会有风险集中的问题,所以为了避免HRM系统业务功能对这部分数据过多的影响,一定要把这个模块解耦,你甚至可以认为这是运行在HRM系统内的一个子系统。
与方案一中的问题二原因一样,当用户管理这部分数据共用系统少、功能简单时,我们更多地选择方案二;当功能越来越复杂、管理数据越来越多时,就要考虑采用方案一——独立为一个新系统,否则HRM系统也会因此不堪重负。