简体中文
  • rbac
  • role design
  • rbac implementation

RBAC实战:为你的应用程序实现安全授权

角色访问控制 (RBAC) 的完整指南:掌握权限设计、角色管理和安全授权,并通过实际的 CMS 实现。

Yijun
Yijun
Developer

不要在用户认证上浪费数周时间
使用 Logto 更快地发布安全应用。几分钟内集成用户认证,专注于您的核心产品。
立即开始
Product screenshot

你是否在为你的应用程序实施一个安全和可扩展的授权系统而苦恼?角色访问控制 (RBAC) 是管理用户权限的行业标准,但正确实施它可能具有挑战性。本教程将向你展示如何使用一个真实世界的内容管理系统 (CMS) 示例来构建一个强大的 RBAC 系统。

通过遵循本指南,你将学习:

  • ✨ 如何设计和实现细粒度的权限,以精确控制用户的操作
  • 🔒 将权限组织成有意义的角色的最佳实践
  • 👤 有效处理资源所有权的技术
  • 🚀 使你的授权系统可扩展且易于维护的方法
  • 💡 使用真实世界的 CMS 示例进行实践实现

本教程的完整源代码可在 GitHub 上获得。

理解 RBAC 的基本原理

角色访问控制不仅仅是为用户分配权限。它是关于创建一个结构化的授权方法,平衡安全性和可维护性。

你可以在 Auth Wiki 中了解更多关于 RBAC 是什么 的信息。

以下是我们在实现中将遵循的关键原则:

细粒度权限设计

细粒度的权限使你能够精确控制用户在系统中可以做什么。我们定义用户可以对资源执行的具体操作,而不是像“管理员”或“用户”这样的广泛访问级别。例如:

  • read:articles - 查看系统中的任何文章
  • create:articles - 创建新文章
  • update:articles - 修改现有文章
  • publish:articles - 更改文章的发布状态

资源所有权和访问控制

资源所有权是我们的 CMS 授权设计中的一个基本概念。虽然 RBAC 定义了不同角色可以执行的操作,但所有权为访问控制增加了个人维度:

  • 作者自动获得对他们创建的文章的访问权限
  • 这种自然的所有权模型意味着作者总是可以查看和编辑自己的内容
  • 在处理文章操作时,系统同时检查角色权限或所有权
  • 例如,即使没有 update:articles 权限,作者仍然可以编辑自己的文章
  • 这种设计减少了额外角色权限的需要,同时保持安全性

这种双层方法(角色+所有权)创建了一个更直观和安全的系统。出版商和管理员仍然可以通过他们的角色权限管理所有内容,而作者则保持对自己的作品的控制。

设计安全的 API

让我们通过 API 端点设计我们的 CMS 核心功能:

实现 API 的访问控制

对于每个端点,我们需要考虑访问控制的两个方面:

  1. 资源所有权 —— 用户是否拥有此资源?
  2. 基于角色的权限 —— 用户的角色是否允许此操作?

以下是我们将如何处理每个端点的访问:

端点访问控制逻辑
GET /api/articles- 任何具有 list:articles 权限的人,或作者可以查看自己的文章
GET /api/articles/:id- 任何具有 read:articles 权限的人,或文章的作者
POST /api/articles- 任何具有 create:articles 权限的人
PATCH /api/articles/:id- 任何具有 update:articles 权限的人,或文章的作者
DELETE /api/articles/:id- 任何具有 delete:articles 权限的人,或文章的作者
PATCH /api/articles/:id/published- 仅具有 publish:articles 权限的用户

创建一个可扩展的权限系统

基于我们的 API 访问需求,我们可以定义以下权限:

权限描述
list:articles查看系统中所有文章的列表
read:articles阅读任何文章的完整内容
create:articles创建新文章
update:articles修改任何文章
delete:articles删除任何文章
publish:articles更改出版状态

请注意,这些权限只在访问非自己拥有的资源时需要。文章所有者可以自动:

  • 查看自己的文章(不需要 read:articles
  • 编辑自己的文章(不需要 update:articles
  • 删除自己的文章(不需要 delete:articles

构建有效的角色

现在我们已经定义了我们的 API 和权限,我们可以创建逻辑上将这些权限分组的角色:

权限/角色👑 管理员📝 出版者✍️ 作者
描述完整系统访问权限,用于完全内容管理可以查看所有文章并控制出版状态可以在系统中创建新文章
list:articles
read:articles
create:articles
update:articles
delete:articles
publish:articles

注意:作者无论角色权限如何,自动具有阅读/更新/删除自己文章的权限。

每个角色的设计都考虑了特定的责任:

  • 管理员:拥有对 CMS 的完全控制,包括所有文章操作
  • 出版者:专注于内容审查和出版管理
  • 作者:专注于内容创作

这种角色结构创造了明确的关注点分离:

  • 作者专注于创造内容
  • 出版者管理内容质量和可见性
  • 管理员保持对整个系统的控制

在 Logto 中配置 RBAC

在开始之前,你需要在 Logto Cloud 中创建一个帐户,或者你也可以使用 Logto OSS 版本 来使用自托管的 Logto 实例。

但对于本教程,我们将使用 Logto Cloud 以简化流程。

设置你的应用程序

  1. 转到 Logto 控制台中的“应用程序”以创建一个新的 React 应用程序

CMS React 应用程序

配置 API 资源和权限

  1. 转到 Logto 控制台中的“API 资源”以创建一个新的 API 资源
    • API 名称:CMS API
    • API 标识符:https://api.cms.com
    • 添加权限到 API 资源
      • list:articles
      • read:articles
      • create:articles
      • update:articles
      • publish:articles
      • delete:articles

CMS API 资源详情

创建角色

转到 Logto 控制台中的“角色”以为 CMS 创建以下角色

  • 管理员
    • 拥有所有权限
  • 出版者
    • 拥有 read:articleslist:articlespublish:articles
  • 作者
    • 拥有 create:articles

管理员角色

出版者角色

作者角色

为用户分配角色

转到 Logto 控制台中的“用户管理”部分以创建用户。

在用户详细信息的“角色”选项卡中,你可以为用户分配角色。

在我们的示例中,我们创建了 3 个用户,具有以下角色:

  • Alex:管理员
  • Bob:出版者
  • Charlie:作者

用户管理

用户详情 - Alex

将你的前端与 Logto RBAC 集成

现在,我们已经在 Logto 中设置了 RBAC,我们可以开始将它集成到我们的前端。

首先,按照 Logto 快速启动 将 Logto 集成到你的应用程序中。

在我们的示例中,我们使用 React 进行演示。

在你的应用程序中设置 Logto 后,我们需要添加 RBAC 配置使 Logto 工作。

如果你已经登录,请记得注销并重新登录以使此更改生效。

当用户使用 Logto 登录并请求上述指定 API 资源的访问令牌时,Logto 将向访问令牌添加与用户角色相关的范围(权限)。

你可以使用 useLogto 钩子中的 getAccessTokenClaims 来从访问令牌中获取范围。

然后你可以使用 userScopes 来检查用户是否有权限访问资源。

将你的后端与 Logto RBAC 集成

现在,该将 Logto RBAC 集成到你的后端中了。

后端授权中间件

首先,我们需要在后端添加一个中间件,以检查用户权限、验证用户是否登录,并确定他们是否具有访问某些 API 所需的权限。

如你所见,在这个中间件中,我们验证前端请求是否包含有效的访问令牌,并检查访问令牌的受众是否与我们在 Logto 控制台中创建的 API 资源匹配。

验证 API 资源的原因是我们的 API 资源实际上代表了我们 CMS 后端的资源,并且我们所有的 CMS 权限都与此 API 资源相关联。

由于此 API 资源在 Logto 中代表 CMS 资源,我们的前端代码在向后端发起 API 请求时包含相应的访问令牌:

现在,我们可以使用 requireAuth 中间件来保护我们的 API 端点。

保护 API 端点

对于只能由具有特定权限的用户访问的 API,我们可以直接在中间件中添加限制。例如,文章创建 API 只能由具有 create:articles 权限的用户访问:

对于需要同时检查权限和资源所有权的 API,我们可以使用 hasScopes 函数。例如,在文章列表 API 中,具有 list:articles 权限的用户可以访问所有文章,而作者只能访问他们自己创建的文章:

此时,我们已经完成了 RBAC 实现。你可以查看 完整的源代码 以查看完整实现。

测试 CMS RBAC 实现

现在,让我们使用我们刚刚创建的三个用户来测试我们的 CMS RBAC 实现。

首先,分别以 Alex 和 Charles 登录并创建一些文章。

由于 Alex 拥有管理员角色,他们可以创建、删除、更新、发布和查看所有文章。

CMS 仪表板 - Alex

Charles 拥有作者角色,只能创建自己的文章,且只能查看、更新和删除自己拥有的文章。

CMS 仪表板 - Charles - 文章列表

Bob 拥有出版者角色,可以查看和发布所有文章,但不能创建、更新或删除文章。

CMS 仪表板 - Bob

结论

恭喜!你已经学会了如何在你的应用程序中实现一个强大的 RBAC 系统。

对于更复杂的场景,例如构建多租户应用程序,Logto 提供了全面的组织支持。查看我们的指南 构建多租户 SaaS 应用程序:从设计到实施的完整指南 以了解更多关于实现组织范围访问控制的信息。

编程愉快!🚀