使用范围受限的 API 密钥

API 密钥使我们能够将 Discourse 与其他系统集成,或自动化各种操作。然而,能力越大,责任越大。如果恶意行为者获取了 API 密钥,他们可能访问敏感数据或修改您的站点。为了缓解这一风险并增加一层额外的安全性,您现在可以通过作用域(scopes)来限制 API 密钥的权限。

作用域与允许的参数

在创建新的 API 密钥时,您可以选择所需的作用域。将鼠标悬停在 :grey_question: 图标上,即可查看其功能的简要说明。点击 :link: 按钮,将显示与该作用域关联的 URL。

您还可以选择指定允许的参数。多个值之间请使用逗号分隔。

迁移现有密钥

在添加此功能时,现有的密钥会自动变为“全局”密钥。若要将其迁移至作用域模式,您必须撤销这些密钥并重新创建新的密钥。

添加自定义作用域

插件可以通过调用 add_api_key_scope 方法来添加自定义作用域:

其中,resource 是一个符号,用于对相关作用域进行分组;action 是一个哈希,包含以下属性:

  • actions:一个列表,包含允许的控制器操作。格式为 controller_name#method_name
  • methods:一个 HTTP 方法列表,用于指定允许的方法(例如 %i[get]。使用此项而非 actions,以便根据 HTTP 方法而非控制器操作进行匹配。
  • params:一个列表,包含允许的参数名称。
  • aliases:一个哈希,用于为允许的参数指定不同的名称。

如果您想了解基础作用域是如何定义的,请参阅:

24 个赞

我在使用只读 API 密钥获取分类时似乎收到了 403 响应。

curl -X GET "https://mysite/categories.json" \
-H "Api-Key: mykey" \
-H "Api-Username: system"

该 API 密钥已拥有对主题的 read 和 read_list 权限。例如,使用相同的密钥访问 /top.json 可以正常工作。但当我使用“全局密钥”时,该端点可以正常工作。

我希望在客户端中使用 API 密钥来读取分类和主题列表,因此拥有一个只读密钥非常重要!

有什么建议吗?

1 个赞

有趣的是,如果完全不使用凭据,它竟然能正常工作!

k
curl -X GET "https://mysite/categories.json"

1 个赞

很遗憾,由于可用的端点数量众多,我们开箱即用的范围(scopes)仅包含少数几个。未来我们可能会添加新的范围,但在此期间,您需要自行扩展以满足需求。

如果您使用带范围的 API 密钥,调用未被所选范围包含的端点将无法工作。您可以点击 :link: 按钮查看哪些 URL 被接受。

这仅适用于公开站点。此外,除非您已登录并拥有足够的权限,否则您将无法查看私人分类等内容。

6 个赞

你们是否接受关于更多权限范围的建议?

我希望能利用我们网站的 API 实现以下功能:让另一个网站检查某个邮箱地址是否对应用户,如果存在,则将其添加到某个群组。我信任该网站(它是同一上级组织内的另一个网站),但如果可以的话,将访问权限限制为仅满足所需功能,似乎更为明智。

1 个赞

我非常高兴他们为插件开放了 API。你可以先开发一个插件,看看它是否能被整合到核心中。

2 个赞

我认为对于任何你能想到的通用范围,欢迎提交 PR。例如 group_membership.edit

5 个赞