关于角色与权限分配的问题

问题描述

假设当前应用有两个用户admin和user,需要给admin用户配置所有的权限,比如后台管理、文章管理;需要给user用户配置文章管理的权限,有两种方案都可以实现

  • 方案一
    建立两个角色,一是后台管理员,具有后台管理权限,另一个是文章管理员,具有文章管理权限,给admin赋予后台管理员和文章管理员两个角色,给user赋予文章管理员角色
    这种方案,各角色间没有权限重复,但用户有时需要赋予多个角色
  • 方案二
    也是建立两个角色,一是后台管理员,既具有后台管理权限,又具有文章管理权限,另一个是文章管理员,只具有文章管理权限,给admin赋予后台管理员角色,给user赋予文章管理员角色
    这种方案,每个用户只需要赋予一个角色,但角色之间会有权限的重复

对比两种方案,当有新的权限要加入时,第一种方案一般是给这些新的权限创建一个新的角色,然后把这个新角色赋予给所有需要的用户,当用户数量多时,工作量大;第二种方案则是把新的权限加入到已有的角色中去,这样对用户不需要改动,相对来说角色的数量低于用户数,应该工作量似乎要小些。
请问大家实际应用中,使用哪种方案比较好呢?

本帖已被设为精华帖!
本帖由 Summer 于 7年前 加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 21
Summer

需求

假设当前应用有两个用户admin和user,需要给admin用户配置所有的权限,比如后台管理、文章管理;需要给user用户配置文章管理的权限,有两种方案都可以实现

清单

用户 User:

  1. admin
  2. user

用户组 Role:

  1. 后台管理员
  2. 文章管理员

权限 Permission:

  1. 后台管理权限
  2. 文章管理权限

方案

方案一:

用户组权限

  1. 「后台管理员」权限:1). 后台管理;
  2. 「文章管理员」权限:1). 文章管理;

用户角色

  1. 「admin 用户」所属用户组:1). 「后台管理员」,2). 「文章管理员」;
  2. 「user 用户」所属用户组:1). 「文章管理员」;

方案二:

用户组权限

  1. 「后台管理员」权限:1). 后台管理;2). 文章管理;
  2. 「文章管理员」权限:1). 文章管理;

用户角色

  1. 「admin 用户」所属用户组:1). 「后台管理员」;
  2. 「user 用户」所属用户组:1). 「文章管理员」;

问题:选择方案一还是二?

我建议选择 二,因为更好理解,后面维护起来也更加合理。

加入一个现实生活中 等级 的概念进去,会比较好理解点,如:主编,小编辑。

把 「后台管理员」定义为「高级管理员」,从等级上理解,是最高级,拥有所有权限,相当于 主编

而「文章管理员」,相当于 小编辑,有限的权限,并且权限有可能随时被 主编 移除。

admin 作为 主编 ,被指定为「高级管理员」用户组,并且拥有所有权限。

让用户组来控制权限,权限对于用户来说是透明的,听起来更合理。

7年前 评论

各有优点,我个人倾向于一个用户只有一个角色,这样干只是图简单。一般来说,只会在后台管理系统中使用角色权限控制,而目前公司使用后台系统的人不多,就十几个内部员工,而且角色分工很细
还是得具体场景具体分析。不过,如果是做通用系统,从功能实现来看,我会实现单用户多角色,至于用户怎么使用就交给他们自己决定了。

7年前 评论
Summer

需求

假设当前应用有两个用户admin和user,需要给admin用户配置所有的权限,比如后台管理、文章管理;需要给user用户配置文章管理的权限,有两种方案都可以实现

清单

用户 User:

  1. admin
  2. user

用户组 Role:

  1. 后台管理员
  2. 文章管理员

权限 Permission:

  1. 后台管理权限
  2. 文章管理权限

方案

方案一:

用户组权限

  1. 「后台管理员」权限:1). 后台管理;
  2. 「文章管理员」权限:1). 文章管理;

用户角色

  1. 「admin 用户」所属用户组:1). 「后台管理员」,2). 「文章管理员」;
  2. 「user 用户」所属用户组:1). 「文章管理员」;

方案二:

用户组权限

  1. 「后台管理员」权限:1). 后台管理;2). 文章管理;
  2. 「文章管理员」权限:1). 文章管理;

用户角色

  1. 「admin 用户」所属用户组:1). 「后台管理员」;
  2. 「user 用户」所属用户组:1). 「文章管理员」;

问题:选择方案一还是二?

我建议选择 二,因为更好理解,后面维护起来也更加合理。

加入一个现实生活中 等级 的概念进去,会比较好理解点,如:主编,小编辑。

把 「后台管理员」定义为「高级管理员」,从等级上理解,是最高级,拥有所有权限,相当于 主编

而「文章管理员」,相当于 小编辑,有限的权限,并且权限有可能随时被 主编 移除。

admin 作为 主编 ,被指定为「高级管理员」用户组,并且拥有所有权限。

让用户组来控制权限,权限对于用户来说是透明的,听起来更合理。

7年前 评论
Summer

为什么一直在说合理?

假如有一天,你不在公司,你的同事把新来的主编添加到「高级管理员」用户组后,突然发现居然没有 文章管理权限,他肯定会打电话问你:

什么?高级管理员都没有 「文章管理权限」?

7年前 评论

@Summer 你说的有些道理,不过有些时候等级高的用户并不需要等级低的用户的权限,那些具体工作他只分配给等级低的用户去做,比如,总编并不需要自己亲自去校对文字,这个工作交给小编辑去做就是了,总编只需要赋予某个用户小编辑这个角色就行了。如果他真的需要自己去校对文字,他给自己加个小编辑角色也可以呀。

7年前 评论

@MrJing 说得挺中肯,比较同意你的看法

7年前 评论

@Summer 还有,有时候等级高的用户并不熟悉具体的业务(比如一个公司的总裁),给他全部的权限,弄不好,他不小心还破坏了某个业务的操作,这个时候我们还是把具体的业务权限赋给等级低的、负责具体业务的用户为好。

7年前 评论
Summer

@程事不足 两种方法都是可行的,只是在讨论哪种方法对于用户来说更好理解,需不需要跟用户多解释,尤其是非程序员用户。

主编明明有高级管理员权限,却无法编辑管理文章,然后你跟他说,你需要 小编辑角色

权限和用户组的关系很容易混淆,方案一把用户组当权限来用了,想想看,是不是不需要用户组,直接拿用户挂钩权限即可?

7年前 评论

我说一下我开发一直使用的权限逻辑。

  1. 一个人可以设置多个角色
  2. 角色和权限是彻底分离
  3. 权限可以分配给人
  4. 角色的权限和人的权限是个继承并覆盖的关系,例如,文章管理员有删除文章的权限,这个人是文章管理员,可以单独给这个人赋予管理人员的权限,但是删除文章的权限默认继承,并且可以取消他的删除文章权限。最后有个恢复默认权限的功能
  5. 不同角色的权限叠加可以设置严格模式和非严格模式(同一个权限在不同角色的值不同时是用 or 或 and 处理)
  6. 必要时给角色添加 weight 进行层级管理,想处理更细的话,甚至在角色创建的时候选择角色类型也就是角色分组(例如,管理员、省级角色、市级角色、区级角色等等),然后每个类型下面可以设置不同的角色,然后这些角色就有了层级之分,对业务逻辑方面很有用。角色类型也有自己的权限,这样 一个人的权限 = 个人权限 覆盖 角色权限 覆盖 角色类型权限
7年前 评论

我个人感觉一个用户多个角色比较合理!一直都是参考tp自带的用户权限

7年前 评论
  • 方案一不像是角色,更像是权限组
  • 不建议多角色,关系复杂会导致以后程序维护成本高,管理起来也会乱
  • 不建议给用户直接赋予权限,道理同上一条
7年前 评论

@Summer 方案一不是拿权限当用户组的,我上面例子中后台管理员具有后台管理权限,这里说的后台管理权限其实是多个权限,比如用户管理,日志管理,角色管理等等,即便我说的文章管理权限在具体设计中也是包含文章建立,文章编辑,文章删除,文章审核等多个权限的

7年前 评论

一开始工作的时候也很纠结,现在我会选择二。

就如 @Notalone 说的,方案一就变成权限组了,Model 应该是:User, PermissionGroup, Permission ,而不是 User, Role, Permission 。

7年前 评论
monkey

我会选择方案二

方案一是程序员思维,快速解决问题,但是不便于日后的维护。

方案二是产品思维,这样的权限划分让人更容易理解,能让一般人扫一眼就能了解每个用户的权限范围。

7年前 评论

楼主可以看一下zendframework的 Permission模块,ACL、Rbac 或许会得到一些提示。

7年前 评论

当是在开发我的系统CITS的时候也遇到了这个问题。我是这么看的,软件是以人为本的。所以,软件的各项功能应该每个用户都有权限来操作,层级是协作思想和管理手段,不属于软件的范畴。

打个比方:

在公司管理中,员工是可以骂领导的,但是他不会那么做,但是不是因为他的职位不让他那么做,而是他所身处的利益不让他那么做,即便是给他权限他也不会用的
在比如,领导他不会去干低层的员工的工作,因为这不符合他的利益。如果他干了,他还真当不上领导。

从这些来看,软件是自由的,协作则是有规矩的。那么,在设计软件的时候,就不需要再纠结权限的问题了。只需要将操作日志记录下来就行了,有跟踪有记录,他是不会轻易操作他职责范围之外的事情的。

附:我写的小感悟

一点儿个人感悟——什么是以人为本的软件开发思想
大多数的软件是通过规则去限制使用者的范围,也就是在用设限的方式实现管理和协作的目的。这种设计思想是一种中心化的设计思想。
CITS设计之初就明确了『以人为本』的思路。在江边望海看来,人类是自由的,协作是自然发生的,不存在谁管理谁的概念。让自然法则成为协作的法则,那么怎么去理解呢。
当一个人有一个想法做一件事情的时候,他需要考虑怎么做,如何做。将未来的目标通过拆解成具体的任务落地,然后找到适合的任务执行人去执行。他的目标是否能完成在于他是否+

将目标拆解到可以落地,被具体的人执行;
他需要给协作人讲明白,用协作人能够听得懂的可以理解的语言;
能够使用工具记录协作数据进而优化协作过程中的问题;
所以,诸如:需求的讲解,任务的拆解如果按照中心化的思想很容易造成,用行政命令强制让任务执行人为目标人的能力缺陷买单,进而会损伤整个团队的协作效率。
借用supercell创始人的理念,每个cell都是独立的他们需要为他们的想法负责,让市场去验证每个cell有没有存在的价值,这其实就是一种自然法则的协作方式,从达尔文进化学的角度看是最优。

7年前 评论

@MrJing 我在开发oa的时候也是多个用户一个角色,不会一个用户多个角色,特别是继承关系,用户用的时候会特别不好理解,最后权限错乱得不偿失。

7年前 评论

做权限依赖 这些问题就解决了,控制粒度可以自由收放

7年前 评论

@Jinrenjie 您好 ,权限依赖是什么概念,能说下吗?

7年前 评论

第二种吧 结构清晰 管理方便

6年前 评论

初来乍到 我觉得两个方案可以合并一下 一个人可以拥有多个角色 一个角色可以拥有多个权限 每个角色之间的权限也可以重复 这样的话是不是两者就可以兼得

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!