在rails + doorkeeper中使用grant_type = password在访问令牌请求中强制设置client_id和secret

时间:2015-02-16 05:55:38

标签: ruby-on-rails devise oauth-2.0 doorkeeper

目前我在使用doorkeeper的rails中的请求中有一个访问令牌api,其中包含用户名,密码和grant_type作为密码。但我需要将client_id和secret作为请求中的必填字段。我怎样才能做到这一点。任何人都可以帮助这个。

在我的doorkeeper.rb配置文件中,

resource_owner_from_credentials do |routes|
#client = OAuth2::Client.new(request.params[:client_id], request.params[:client_secret], site: "http://localhost:3000/")
#auth_url = client.auth_code.authorize_url(:redirect_uri => "urn:ietf:wg:oauth:2.0:oob")
request.params[:user] = {:email => request.params[:username], :password => request.params[:password]}
request.env["devise.allow_params_authentication"] = true
request.env["warden"].authenticate!(:scope => :user)
end

我想使用用户凭据进行身份验证,并且还希望将client_id和secret设为必填字段。如果缺少client_id和secret,我想显示一条消息。

2 个答案:

答案 0 :(得分:2)

在该区块内,您可以检查是否存在params[:client_id]params[:client_secret],并进行必要的检查以确保它们有效:)

resource_owner_from_credentials do |routes|

  raise Doorkeeper::Errors::DoorkeeperError if params[:client_id].blank? || params[:client_secret].blank?
  dk_app = Doorkeeper::Application.find_by(uid: params[:client_id])
  raise Doorkeeper::Errors::DoorkeeperError if dk_app.blank? || dk_app.secret != params[:client_secret]

  ## here do some checking that the client_id and secret are valid

  request.params[:user] = {:email => request.params[:username], :password => request.params[:password]}
  request.env["devise.allow_params_authentication"] = true
  request.env["warden"].authenticate!(:scope => :user)
end

如果您需要将错误消息更改为自定义消息,可以参考this issue

答案 1 :(得分:2)

您可以将此代码添加到您的doorkeeper.rb配置文件

# Doorkeeper patch: Always require a client on resource owner password flow
Doorkeeper::OAuth::PasswordAccessTokenRequest.class_eval do
  private
  def validate_client
    !!client
  end
end

确保密码流始终需要客户端应用程序。然后由Doorkeeper在内部验证client_id和client_secret。如果它们无效,则会提供门卫针对该案例的默认错误消息。

猴子补丁总是很难看,但由于门卫并不真正允许本地自定义这种行为,我认为它现在是一个有效的解决方案。