Rails: 来自上下文的门卫自定义响应

Rails: Doorkeeper custom response from context

我们正在使用 Doorkeeper gem 通过 API 来验证我们的用户。自从我们几年前实施以来,一切正常,我们正在使用 password 授权流程,如示例所示:

resource_owner_from_credentials do |_routes|
  user = User.active.find_for_database_authentication(email: params[:username])

  if user&.valid_password?(params[:password])
    sign_in(user, force: true)
    user
  end
end

Doorkeeper 与 Devise 结合使用,可启用 reconfirmable 策略。正如您在上面的代码中看到的,我们只允许 active 用户(a.k.a 具有确认电子邮件的用户)连接:

User.active.find_.....

问题

我们的规范已更改,现在我们希望 return 登录时出现不同的错误(针对 /oauth/token),具体取决于用户是否已确认其电子邮件。 现在,如果登录失败,Doorkeeper 正在 returning 以下 JSON:

{
  "error": "invalid_grant",
  "error_description": "The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."
}

理想情况下,当且仅当当前尝试登录的电子邮件是 unconfirmed

时,我们希望能够 return 自定义描述

我们已经检查了有关 Doorkeeper 的文档,但它似乎没有一个简单的方法(如果有的话)来执行此操作。 resource_owner_from_credentials 方法位于配置中这一事实增加了太多魔力,但灵活性不够。

有什么想法吗?

好的,在深入研究之后,我们找到了一种解决此问题的简单方法,方法是重写 Doorkeeper::TokensController

# frozen_string_literal: true

class TokensController < Doorkeeper::TokensController
  before_action :check_if_account_is_pending, only: :create

  private

  def check_if_account_is_pending
    user = User.find_by(email: params['username'])
    render json: unconfirmed_account_error if user && !user.confirmed?
  end

  def unconfirmed_account_error
    { error: 'invalid', error_description: 'You must validate your email address before login' }
  end
end

我们还需要确保路由指向自定义控制器:

use_doorkeeper do
  controllers tokens: 'tokens'
end

希望对以后的人有所帮助