用户API密钥规范

经过一些尝试和错误,我终于让它运行起来了。

以下是我遵循的基本步骤:当我有一个自己编写的应用程序,并希望用户能够使用该应用向 Discourse 站点发起 API 调用时,我会这样做。

为此,我需要为每个特定用户生成一个专属的 API 令牌,以便代表该用户进行调用(至少在 Node.js/JavaScript 环境中是这样)。


注意:在 JavaScript 方面,我发现 @KengoTODA 在此处提供的代码非常有帮助:discourse-api-key-generator/src/index.ts at main · KengoTODA/discourse-api-key-generator · GitHub


以下是我遵循的步骤:

第一步:生成一对公钥和私钥。

这是你的应用程序需要完成的工作——生成一个公钥和一个私钥。上面的 GitHub Gist 提供了一种实现方法。

第二步:设置一个重定向 URL。

这是 Discourse 将重定向到的 URL,并在其载荷(payload)中提供最终的 API 令牌。如果你使用的是桌面应用程序(即没有浏览器 URL 的应用),那么重定向 URL 将基于你自定义的协议设置,当在浏览器中输入该重定向 URL 时,会打开你的应用程序。

请注意,重定向 URL 需要在目标 Discourse 站点的站点设置中进行白名单配置。

此外,Discourse 站点可能还需要启用“允许用户 API 密钥”的站点设置。关于“站点设置”的详细说明,请参阅该主题的原帖。

第三步:向 Discourse 的请求 URL 发送 API 请求调用。

因此,你的应用程序将向遵循以下格式的 URL 发送调用:

https://[你的目标 Discourse 站点.com]/user-api-key-new

并添加以下参数:

  • 你的应用名称
  • 你的“client_id”(对于桌面应用,我使用了 const {hostname} = require('os') 中的 hostname(),就像上面提到的 GitHub Gist 中一样)
  • 作用域(scopes,即你希望用户通过 API 能够执行的操作范围,例如 “write”、“read” 等)
  • 你的公钥(来自第一步)
  • 你的重定向 URL(来自第二步)
  • nonce(这是一个你可以自定义的值——例如,直接使用 ‘1’ 似乎就能正常工作)

第四步:用户在由请求 URL 打开的 Discourse 站点页面上授权你的应用

当你成功发送请求 URL 后,它会打开 Discourse 站点上的一个页面,告知用户你的应用希望访问该站点。

在该页面上,有一个按钮供用户允许此操作。当用户点击该按钮时,Discourse 站点会重定向到你提供的重定向 URL,并在参数中附加 ?payload=[API 密钥]。这里的 API 密钥就是你需要在应用中解码的密钥。

第五步:你的应用获取重定向 URL 的值(包含 payload 值),并解码 API 密钥

你快要成功了。你的应用程序需要解析 Discourse 重定向到的 URL,并获取载荷中包含的 API 密钥。

一旦你获得了该 API 密钥,你需要做两件事:

  1. 获取实际的密钥,而不是 URL 编码版本:如果你从 URL 中获取参数,它通常会被 URL 编码(例如添加 % 等)。你需要对其进行清理。在 JavaScript 中,我发现 decodeURIComponent 可以解决这个问题。
  2. 一旦你获得了从 Discourse 返回的已清理的 API 密钥,你需要对其进行解码。为此,你可以使用 JavaScript 配合私钥进行解码。基本上,你使用你在第一步中生成的私钥来解码已清理的 API 密钥。我在上面提到的 GitHub Gist 中提供了一些 JavaScript 示例代码:discourse-api-key-generator/src/index.ts at main · KengoTODA/discourse-api-key-generator · GitHub

运行你的解码代码后,你就得到了令牌本身,现在可以代表用户进行经过身份验证的 API 调用了。

第六步:使用该令牌(即最终的、已清理的、已解码的 API 密钥)代表用户发起 API 调用

使用该令牌后,你似乎不需要在 API 调用中输入用户名。我发现,在 GET、POST、PUT 等调用中包含以下头部就足够了:

headers: {
"User-Api-Key": [令牌]
}

至此,你 hopefully 已经拥有一个可用的每用户身份验证方法,用于与 Discourse 进行交互。

7 个赞