RBAC实战:为你的应用程序实现安全授权
角色访问控制 (RBAC) 的完整指南:掌握权限设计、角色管理和安全授权,并通过实际的 CMS 实现。
角色访问控制 (RBAC) 的完整指南:掌握权限设计、角色管理和安全授权,并通过实际的 CMS 实现。
你是否在为你的应用程序实施一个安全和可扩展的授权系统而苦恼?角色访问控制 (RBAC) 是管理用户权限的行业标准,但正确实施它可能具有挑战性。本教程将向你展示如何使用一个真实世界的内容管理系统 (CMS) 示例来构建一个强大的 RBAC 系统。
通过遵循本指南,你将学习:
本教程的完整源代码可在 GitHub 上获得。
角色访问控制不仅仅是为用户分配权限。它是关于创建一个结构化的授权方法,平衡安全性和可维护性。
你可以在 Auth Wiki 中了解更多关于 RBAC 是什么 的信息。
以下是我们在实现中将遵循的关键原则:
细粒度的权限使你能够精确控制用户在系统中可以做什么。我们定义用户可以对资源执行的具体操作,而不是像“管理员”或“用户”这样的广泛访问级别。例如:
read:articles - 查看系统中的任何文章create:articles - 创建新文章update:articles - 修改现有文章publish:articles - 更改文章的发布状态资源所有权是我们的 CMS 授权设计中的一个基本概念。虽然 RBAC 定义了不同角色可以执行的操作,但所有权为访问控制增加了个人维度:
update:articles 权限,作者仍然可以编辑自己的文章这种双层方法(角色+所有权)创建了一个更直观和安全的系统。出版商和管理员仍然可以通过他们的角色权限管理所有内容,而作者则保持对自己的作品的控制。
让我们通过 API 端点设计我们的 CMS 核心功能:
对于每个端点,我们需要考虑访问控制的两个方面:
以下是我们将如何处理每个端点的访问:
| 端点 | 访问控制逻辑 |
|---|---|
| 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 | ✅ | ✅ | ❌ |
注意:作者无论角色权限如何,自动具有阅读/更新/删除自己文章的权限。
每个角色的设计都考虑了特定的责任:
这种角色结构创造了明确的关注点分离:
在开始之前,你需要在 Logto Cloud 中创建一个帐户,或者你也可以使用 Logto OSS 版本 来使用自托管的 Logto 实例。
但对于本教程,我们将使用 Logto Cloud 以简化流程。

list:articlesread:articlescreate:articlesupdate:articlespublish:articlesdelete:articles
转到 Logto 控制台中的“角色”以为 CMS 创建以下角色
read:articles、list:articles、publish:articlescreate:articles


转到 Logto 控制台中的“用户管理”部分以创建用户。
在用户详细信息的“角色”选项卡中,你可以为用户分配角色。
在我们的示例中,我们创建了 3 个用户,具有以下角色:


现在,我们已经在 Logto 中设置了 RBAC,我们可以开始将它集成到我们的前端。
首先,按照 Logto 快速启动 将 Logto 集成到你的应用程序中。
在我们的示例中,我们使用 React 进行演示。
在你的应用程序中设置 Logto 后,我们需要添加 RBAC 配置使 Logto 工作。
如果你已经登录,请记得注销并重新登录以使此更改生效。
当用户使用 Logto 登录并请求上述指定 API 资源的访问令牌时,Logto 将向访问令牌添加与用户角色相关的范围(权限)。
你可以使用 useLogto 钩子中的 getAccessTokenClaims 来从访问令牌中获取范围。
然后你可以使用 userScopes 来检查用户是否有权限访问资源。
现在,该将 Logto RBAC 集成到你的后端中了。
首先,我们需要在后端添加一个中间件,以检查用户权限、验证用户是否登录,并确定他们是否具有访问某些 API 所需的权限。
如你所见,在这个中间件中,我们验证前端请求是否包含有效的访问令牌,并检查访问令牌的受众是否与我们在 Logto 控制台中创建的 API 资源匹配。
验证 API 资源的原因是我们的 API 资源实际上代表了我们 CMS 后端的资源,并且我们所有的 CMS 权限都与此 API 资源相关联。
由于此 API 资源在 Logto 中代表 CMS 资源,我们的前端代码在向后端发起 API 请求时包含相应的访问令牌:
现在,我们可以使用 requireAuth 中间件来保护我们的 API 端点。
对于只能由具有特定权限的用户访问的 API,我们可以直接在中间件中添加限制。例如,文章创建 API 只能由具有 create:articles 权限的用户访问:
对于需要同时检查权限和资源所有权的 API,我们可以使用 hasScopes 函数。例如,在文章列表 API 中,具有 list:articles 权限的用户可以访问所有文章,而作者只能访问他们自己创建的文章:
此时,我们已经完成了 RBAC 实现。你可以查看 完整的源代码 以查看完整实现。
现在,让我们使用我们刚刚创建的三个用户来测试我们的 CMS RBAC 实现。
首先,分别以 Alex 和 Charles 登录并创建一些文章。
由于 Alex 拥有管理员角色,他们可以创建、删除、更新、发布和查看所有文章。

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

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

恭喜!你已经学会了如何在你的应用程序中实现一个强大的 RBAC 系统。
对于更复杂的场景,例如构建多租户应用程序,Logto 提供了全面的组织支持。查看我们的指南 构建多租户 SaaS 应用程序:从设计到实施的完整指南 以了解更多关于实现组织范围访问控制的信息。
编程愉快!🚀