为什么我的 Doorkeeper 配置会收到 401 Unauthorized 错误?

Why am I receiving 401 Unauthorized errors with my Doorkeeper configuration?

我有一个 Rails 6.1 应用程序,使用 devise 4.7.1、doorkeeper 5.5.1 和 devise-doorkeeper 1.2.0。

我正在尝试 运行 通过 (PKCE) OAuth 流程,但最后一步 -- POST 对 /oauth/token 的请求 -- returns JSON 内容 {"error": "You need to sign in or sign up before continuing."}.

的 401 未经授权错误

我对此感到困惑,因为据我所知,未经身份验证的用户应该可以访问 /oauth/token 端点。同样奇怪的是(但也许是转移注意力),如果我尝试 运行 使用 curl 的相同 POST 请求,但删除 User-Agent header,它会成功。

我目前怀疑是 initializers/doorkeeper.rb 中的这段代码:

  resource_owner_authenticator do
    current_user || warden.authenticate!(scope: :user)
  end

这来自Doorkeeper docs。通过单步执行代码,我可以看到 returns 是对 warden.authenticate! 的调用 401 错误。门卫的 TokensController#create 从未被叫到。

我是否遗漏了允许未经身份验证访问此 TokensController#create 端点的任何重要步骤?

这个问题是由于我们使用了 Ahoy analytics library.

默认情况下,此库会跟踪您的 Rails 应用中的所有页面访问。它尝试使用 current_user || current_resource_owner 获取当前用户。因为当 POST 到 /oauth/tokencurrent_user 仍然是 nil,得到 current_resource_owner 最终调用了我们的门卫 resource_owner_authenticator,它返回了 401 错误。 The source code for this is here.

这也解释了为什么在取消设置 User-Agent header 时一切正常:没有用户代理(或例如 curl 的用户代理),Ahoy 将请求视为来自机器人,并且不会尝试跟踪它 (source code here)。

我们的解决方案是告诉 Ahoy 通过在其配置中设置 Ahoy.api_only = true 来自动停止跟踪所有页面浏览量。