跳到主要内容

保护全局 API 资源

使用 Logto 的基于角色的访问控制 (RBAC) 保护产品范围内的 API。分配全局角色和权限,以控制你应用中所有用户和客户端的访问。

什么是全局 API 资源?

全局 API 资源是你应用中所有用户都可以访问的端点或服务,无论属于哪个组织或租户。这些通常是面向公众的 API、核心产品服务,或任何不限定于特定组织的端点。

使用场景包括

  • 在你的用户群体中共享的公共 API 或端点。
  • 不绑定多租户的微服务。
  • 所有客户都使用的核心应用 API(如 /api/users/api/products)。

Logto 允许你结合 OAuth 2.1 和灵活的基于角色的访问控制来保护这些 API。

在 Logto 中如何工作

  • API 资源和权限是全局注册的:你想要保护的每个 API 都用唯一的资源指示器(URI)和一组控制访问的权限(scopes)进行定义。
  • 访问由全局角色控制:你可以将权限分配给角色,然后将角色分配给用户或客户端。
  • 与组织级权限分离:全局 API 资源没有组织上下文。但如有需要,可以与组织角色结合使用,提供额外的上下文层。要保护组织级 API,请参见 保护组织级 API 资源
全局 API 资源 RBAC

实现概览

  1. 注册你的 API 资源 并在 Logto 中定义其权限。
  2. 定义角色,为访问 API 分配所需权限。
  3. 分配角色 给用户或客户端。
  4. 使用 OAuth 2.0 授权流程 获取 API 的访问令牌(resource 参数必须与注册的 API 标识符一致)。
  5. 在你的 API 中验证访问令牌,以强制执行权限。

理解资源指示器

Logto 按照 RFC 8707: OAuth 2.0 的资源指示器 建模 API 资源。资源指示器 是唯一标识所请求目标 API 或服务的 URI。

要点

  • 资源指示器必须是绝对 URI(如 https://api.example.com
  • 不包含片段部分;尽量避免使用查询字符串。
  • 资源指示器支持受众限制令牌和多 API 架构。

示例

  • Management API: https://my-tenant.logto.app/api
  • 自定义全局 API: https://api.yourapp.com

授权流程:认证 (Authentication) 并保护你的 API

以下流程适用于交互式用户认证 (Authentication)(浏览器 / 应用)和后端机器对机器 (M2M) 场景。

请注意,该流程未包含所有必需参数或头信息的详细说明,重点展示关键步骤。继续阅读以了解实际流程。

用户认证 (Authentication) = 浏览器 / 应用。M2M = 使用客户端凭证的后端服务或脚本。

备注:

resource 参数必须与 Logto 中注册的 API 标识符(资源指示器)完全一致。

实现步骤

注册你的 API 资源

  1. 前往 控制台 → API 资源
  2. 创建新的 API 资源(如 https://api.yourapp.com/org),并定义其权限(scopes)。

完整配置步骤见 定义带权限的 API 资源

设置全局角色

  1. 前往 控制台 → 角色
  2. 创建与你 API 权限对应的角色(如 read:productswrite:products)。
  3. 将这些角色分配给需要访问 API 的用户或客户端。

完整配置步骤见 使用全局角色

获取全局 API 资源的访问令牌

在访问全局 API 资源前,你的客户端必须获取访问令牌。Logto 会为全局 API 资源签发 JSON Web Token (JWT) 作为访问令牌。通常使用 OAuth 2.0 授权码流程刷新令牌流程客户端凭证流程 完成。

授权码或刷新令牌流程

所有 Logto 官方 SDK 都原生支持使用刷新令牌流程获取全局 API 资源的访问令牌。你也可以用标准 OAuth 2.0 / OIDC 客户端库实现该流程。

初始化 Logto 客户端时,将资源指示器添加到 resources 参数(数组),然后将所需权限(scopes)添加到 scopes 参数。

用户认证 (Authentication) 后,请在请求访问令牌时(如调用 getAccessToken())传递资源指示器到 resource 参数或类似参数中。

各 SDK 详情见 快速开始

客户端凭证流程

对于机器对机器 (M2M) 场景,你可以使用客户端凭证流程获取全局 API 资源的访问令牌。通过向 Logto 的 /oidc/token 端点发起 POST 请求,使用你的客户端 ID 和密钥请求访问令牌。

请求中需包含两个关键参数:

  • resource:你要访问的 API 的资源指示器 URI(如 https://api.yourapp.com)。
  • scope:你要请求的 API 权限(如 read:products write:products)。

以下是使用客户端凭证模式的令牌请求非规范示例:

POST /oidc/token HTTP/1.1
Host: your.logto.endpoint
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)

grant_type=client_credentials
&resource=https://api.yourapp.com
&scope=read:products write:products

在你的 API 中验证 JWT 访问令牌

Logto 签发的 JWT 包含你的 API 可用于强制授权 (Authorization) 的声明 (Claims)。

当你的 API 收到带有 Logto 签发的访问令牌的请求时,你应:

  • 验证令牌签名(使用 Logto 的 JWKs)。
  • 确认令牌未过期(exp 声明 (Claim))。
  • 检查 iss(发行者 (Issuer))是否与你的 Logto 端点一致。
  • 确保 aud(受众 (Audience))与你注册的 API 资源标识符一致(如 https://api.yourapp.com)。
  • 拆分 scope 声明 (Claim)(以空格分隔),检查所需权限。

分步和特定语言指南见 如何验证访问令牌

可选:处理用户权限变更

信息:

👷 功能开发中。🚧

最佳实践与安全建议

  • 权限应以业务为驱动:使用能映射到实际操作的清晰名称。
  • 令牌过期时间应短:如果令牌泄露可降低风险。
  • 限制授予的权限 (Scopes):只给令牌实际需要的权限。
  • 使用受众限制:始终验证 aud 声明 (Claim),防止滥用。

常见问题

如果我的客户端不支持 resource 参数怎么办?{what-if-my-client-doesn-t-support-the-resource-parameter}

在 Logto 控制台设置默认 API 资源。当令牌请求中未指定 resource 参数时,令牌将默认使用该受众 (Audience)。

为什么我的 API 返回 401 未授权?{why-do-i-get-401-unauthorized-from-my-api}

请检查以下常见问题:

  • 令牌签名:确认你的后端从 Logto 获取了正确的 JWKs
  • 令牌过期:确保令牌未过期(exp 声明 (Claim))
  • 受众 (Audience):确认 aud 声明 (Claim) 与你注册的 API 资源指示器一致
  • 所需权限 (Scopes):确认令牌的 scope 声明 (Claim) 包含所需权限

如何在没有完整客户端的情况下测试?{how-do-i-test-without-a-full-client}

使用 个人访问令牌 模拟认证 (Authentication) 调用。这样你可以在不实现完整 OAuth 流程的情况下测试 API 端点。

请求权限时可以使用 scope 前缀或简写吗?{can-i-use-scope-prefixes-or-shortened-versions}

不可以。Scope 名称必须完全匹配你在 API 资源中定义的权限名称。前缀和简写不能作为通配符使用。

示例:

如果你的 API 资源定义了:

  • read:elections
  • write:elections

你必须请求:

scopes: ["read:elections", "write:elections"]

这样不会生效

scopes: ["read", "write"]  // ❌ 不匹配权限名称

延伸阅读

如何验证访问令牌

RBAC 实践:为你的应用实现安全授权 (Authorization)

自定义令牌声明 (Claims) RFC 8707: 资源指示器