1. RBAC入门:从混乱到有序的权限管理之路

说实话,每次接手新项目,看到那种直接给用户绑权限的代码,我就头疼。你想想看,用户表里一堆权限字段,每次新增功能就得改数据库,这日子什么时候是个头?

RBAC 就是为了解决这种混乱而生的。它不是什么新概念,但直到今天,我依然认为它是企业级权限管理最优雅的方案之一。

1.1 RBAC 发展史:我见证的权限进化

RBAC 的历史,说白了就是权限管理从“野蛮生长”到“标准化”的过程。

  • 90年代初:David Ferraiolo 和 Richard Kuhn 在美国国家标准局提出了 RBAC 的概念。当时主要为了统一政府机构的权限模型。
  • 1992年:正式发表,第一次系统定义了“角色”这个中间层。
  • 2004年:成为美国国家标准(ANSI INCITS 359-2004)。这也是我现在做设计时最常用的参考标准。
  • 至今:衍生出 RBAC0、RBAC1、RBAC2、RBAC3 四个等级,逐步加入了角色继承、职责分离等高级特性。
一点个人经验:我实际项目中用得最多的是 RBAC0 加上一些 RBAC2 的约束规则。大部分业务场景下,一个基础模型加上合理的组织架构就够了。不要为了炫技而上复杂的继承体系,容易把自己坑进去。

1.2 三个核心概念:用户、角色、权限

这就是 RBAC 的精髓了——在“用户”和“权限”之间加一层“角色”。

概念 我把它理解成 真实项目中的例子
用户(User) 干活的人 张三、李四,你的 App 里的某个账号
角色(Role) 职位或岗位 管理员、运营专员、普通用户
权限(Permission) 操作按钮或接口 “创建订单”、“删除用户”、“查看报表”

记住一个口诀:用户只能通过角色获得权限,角色是权限的集合。

我在项目中遇到过一个团队,他们让每个用户直接勾选一堆“操作”。权限多了以后,新增一个功能,要通知上百个用户去重新勾选……嗯,后来他们改用 RBAC 了。

为什么不用“用户-权限”直接绑定?

直接绑定不是不能用,但管理成本太高。你想想看:

  • 100个用户、20种权限,直接绑就是100×20=2000条关系。
  • 引入角色后,10个角色就能覆盖所有场景,每个角色关联权限,用户关联角色即可。

角色就是那个“稳定层”。权限变化频繁,但岗位和职责相对稳定。

1.3 应用场景:什么时候该上 RBAC?

不是所有系统都需要 RBAC。但我个人习惯,只要系统存在多用户、多数据、多操作这三个特征,我就直接上。因为后期重构的成本真的很高。

几个典型场景:

  1. SaaS 平台:不同租户拥有不同的管理角色,比如超级管理员、项目管理员、只读用户。
  2. 企业内部系统:OA、CRM、ERP,不同岗位看到不同菜单。
  3. 运营后台:运营、财务、客服,每个角色的操作边界清清楚楚。
避坑指南:我曾经见过一个团队,把“数据权限”和“功能权限”混在一起做。结果就是角色A能看到北京的全部订单,但看不到上海的。这种颗粒度的控制,光靠 RBAC 的基础模型是不够的,需要结合数据级权限的扩展设计。后面我会专门讲这个。

1.4 RBAC 的核心优势:我为什么推荐它

做 SDK 适配时,RBAC 的好处就更明显了:

  • 解耦:SDK 只需要关心“角色-权限”的映射,不需要知道用户是谁。
  • 可扩展:新增一种角色,SDK 这边配一套权限规则就好,不用改核心代码。
  • 审计友好:查日志时,看到“角色A的权限被修改”,比看到“张三的权限被修改”更清晰——因为你知道这个角色下有好几十个人。

说白了,RBAC 就是一种降低认知复杂度的抽象手段。你不需要记住每个人的权限,记住几个角色就行。

RBAC 核心关系图谱 用户 (User) 角色 (Role) 权限 (Permission) 会话 (Session) 约束条件 (职责分离等) 分配 授予 激活 限制 核心逻辑:用户不能直接拥有权限,必须通过角色这个“中间层”来获得。
重要提示:上图中的“会话”和“约束条件”在 RBAC0 基础模型中是可选的。但在 SDK 设计中,我会强烈建议把会话管理纳入进来,因为一个用户可以同时扮演多个角色,而会话决定了“当前上下文下,你激活了哪些角色”。这个细节在后期做鉴权拦截时非常关键。

1.5 一个简单的代码示例:如何定义模型

我在 SDK 里一般这样定义基础数据结构:

# 用户实体
class User:
    def __init__(self, user_id, name):
        self.user_id = user_id
        self.name = name
        self.roles = []

# 角色实体
class Role:
    def __init__(self, role_id, name):
        self.role_id = role_id
        self.name = name
        self.permissions = []

# 权限实体
class Permission:
    def __init__(self, perm_code, name):
        self.perm_code = perm_code
        self.name = name

# 核心判断逻辑
def has_permission(user, perm_code):
    for role in user.roles:
        for perm in role.permissions:
            if perm.perm_code == perm_code:
                return True
    return False

这个例子很基础,但核心思想到位了。实际项目中,我通常会把查询缓存起来,因为角色分配关系变化不频繁。

注意:一定要区分“角色ID”和“角色名称”。我在代码里用角色ID做关联,角色名称只做展示。为什么?因为你今天叫“管理员”,明天可能改叫“超级管理员”,如果代码里写了字符串匹配,那改起来就炸了。

1.6 小结:学了这章,你应该带走什么

  • 三个概念:用户、角色、权限,角色是中间的桥梁。
  • 一个关系:用户-角色-权限,三者构成 RBAC 的骨架。
  • 一个原则:权限最小化,角色设计要符合业务实际。

好了,这就是 RBAC 的入门。下节课我们会深入到 RBAC 的几种标准模型,看看在不同的 SDK 场景里,我们该选 RBAC0 还是 RBAC2。嗯,到时候我会用一个真实的 SDK 项目踩坑案例来讲解。