如何在 AJAX 调用中使用 API 密钥?

我试图通过 Discourse API 以编程方式获取有关某个群组的信息。我在自定义仪表板的 < /head> 部分中编写了相关代码。我是论坛的管理员。

但代码无法运行,我认为问题可能在于我不理解 API 密钥的工作原理。

如果我希望 Discourse 在每次有用户访问特定页面时,自动调用 API 以获取某个群组的信息,那么正确的 API 密钥设置应该是什么?

目前我的设置如下:

在仪表板中,我进入了 API → 新建 API 密钥。在那里,我需要选择“用户级别”。抱歉问这么基础的问题,但这里的“用户级别”是什么意思?(API 调用需要在任何用户访问指定页面时运行)。

我选择了“所有用户”,然后生成了令牌。

接着,在自定义 CSS/HTML 仪表板的 < /head> 部分,我在相关的 标签之间输入了以下代码:

var groupName = [相关群组名称]
var token = [我生成的令牌]
$.ajax({
     url: 'https://myforum.com/groups/groupName.json',
      contentType: "application/json",
      headers: {
          "Api-Key": token,
          "Api-Username": "system"
        },
        dataType: 'json',
        success: function(result){
             console.log('result = ' + result);
         }
})

代码确实执行了,但返回了一个错误,提示“未授权”(尽管我是管理员,并且也是我所测试群组的成员)。

我需要修改哪些内容?

这不会向所有能访问您网站的人暴露您的“所有用户”API 密钥吗?我认为您需要寻找另一种方法,从主题组件中获取组数据。

如果你需要的群组信息不在用户可用的 JSON 加载数据中,那么你需要想办法将其添加到序列化器中。在现有的主题组件和插件中搜索“add to serializer”、addToSerializer 或 add_to_serializer 可能会有所帮助。

但代码难道不应该在任何情况下都能工作吗?API 提供了获取群组信息的功能。我仍然对它是如何运作的感到困惑。

通常使用 API 获取特定群组信息的正确方式是什么?

我需要的关键信息是用户是否为该群组的群主。此信息会通过 JSON API 返回。因此,当用户访问特定页面时,我希望向 API 发起请求以获取群组信息,其中基本响应应包含当前登录用户是否为群主。

这看起来是 API 的一个 straightforward 实现。然而,该操作似乎需要 API 密钥,但我目前使用的方法并不奏效。

我认为此处无需创建单独的插件或主题组件,因为这是 JSON API 提供的基本操作之一。

我很好奇是否有办法在使用密钥调用 API 时不暴露密钥(即,使用 API 的标准或最佳实践方式是什么)。

编辑:如果出于某种原因此操作不适合通过 API 调用,那么确实需要对其进行序列化。有人能提供可用的代码示例吗?我了解存在 add_to_serializer 方法,但我尚未成功掌握其语法,也一直在寻找该方法的有效示例。

亲爱的 @JQ331

是的,我为你快速检查了一下(作为参考)。我以工作人员身份登录测试论坛,获取了 staff 群组,并得到了预期的结果:

工作人员以工作人员身份获取的 staff 群组的 JSON 对象
{
  "group": {
    "id": 3,
    "automatic": true,
    "name": "staff",
    "display_name": "staff",
    "user_count": 1,
    "mentionable_level": 0,
    "messageable_level": 0,
    "visibility_level": 1,
    "automatic_membership_email_domains": null,
    "primary_group": false,
    "title": null,
    "grant_trust_level": null,
    "incoming_email": null,
    "has_messages": false,
    "flair_url": null,
    "flair_bg_color": null,
    "flair_color": null,
    "bio_raw": null,
    "bio_cooked": null,
    "bio_excerpt": null,
    "public_admission": false,
    "public_exit": false,
    "allow_membership_requests": false,
    "full_name": null,
    "default_notification_level": 3,
    "membership_request_template": null,
    "is_group_user": true,
    "is_group_owner": true,
    "members_visibility_level": 0,
    "can_see_members": true,
    "publish_read_state": false,
    "is_group_owner_display": false,
    "mentionable": false,
    "messageable": false
  },
  "extras": {
    "visible_group_names": [
      "admins",
      "moderators",
      "staff",
      "trust_level_0",
      "trust_level_1",
      "trust_level_2",
      "trust_level_3",
      "trust_level_4"
    ]
  }
}

……此外,我还尝试在退出登录后执行相同操作,也得到了预期结果:

{"errors":["您无权查看请求的资源。"],"error_type":"invalid_access"}

因此,在我看来,这意味着一切功能均按预期正常运行。

供参考 @JQ331,作为已登录用户(通过浏览器),执行此操作时我不需要 API 密钥。

    "is_group_owner": true,

@neounix:非常感谢您的回复,这帮我停止了无谓的搜寻。我原本以为收到未授权响应是因为认证问题。

事实证明您是对的,此操作并不需要 API 密钥。问题其实出在一个(简单的)代码错误上,从我上面贴出的代码中可以清楚地看出来,但我之前忽略了(我错误地将 AJAX URL 的变量名直接写进去了)。

以下是可正常工作的代码:

var groupName = [相关群组名称]
var token = [我生成的令牌]
$.ajax({
     url: 'https://myforum.com/groups/' + groupName + '.json',    //这就是之前出错的地方
      contentType: "application/json",
        dataType: 'json',
        success: function(result){
             console.log('完整响应 = ' + JSON.stringify(result));
             console.log('是否为群组所有者 = ' + result.group.is_group_owner);  //注意,此处值要么是 true,要么是 null           
     }
})

我之前收到未授权响应,是因为之前输入的 URL 中的群组名称不正确(它被当成了字面量 “groupName” 来读取)。