Is there a way to customize error response based on different conditions.
I have a mobile app and I am using resource owner password credentials flow to authenticate it.
So for authentication, I have a few conditions where a user is not authenticated, for example - when a user's state is not active in which I need to show him a message that his account is not yet active.
This may not be according to the Oauth2 specs but is there a way around it.
I followed this, https://github.com/applicake/doorkeeper/issues/299 but i can not have conditions based on this.Or if there is an existing issue related to this, would love if somebody could link me to it(Sorry I tried looking but no luck).
I have implement that by override tokens_controller
Doorkeeper.configure do
resource_owner_from_credentials do |routes|
result = Session.authorize(params[:username], params[:password])
# result be a hash like this { type: ok, user_id: 1111 } or { type: :password_invalid, msg: "password invalid."}
if result[:type] == :ok
User.find_by_id(result[:user_id])
else
params[:__auth_error] = result
raise Doorkeeper::Errors::DoorkeeperError
end
end
end
MyApp::Application.routes.draw do
use_doorkeeper do
controllers tokens: 'tokens'
end
end
class TokensController < Doorkeeper::TokensController
def create
response = strategy.authorize
self.headers.merge! response.headers
self.response_body = response.body.to_json
self.status = response.status
rescue Doorkeeper::Errors::DoorkeeperError => e
auth_error_hash = params[:__auth_error]
if !auth_error_hash.blank?
error_type = auth_error_hash.delete(:type)
error_description = auth_error_hash.delete(:msg)
error = get_error_response_from_exception e
self.headers.merge! error.headers
self.response_body = { error: "invalid_grant", error_type: error_type, error_description: error_description }.merge(auth_error_hash).to_json
self.status = error.status
else
handle_token_exception e
end
end
end
and then the response.body will be:
{"error":"invalid_grant","error_type":"password_invalid","error_description":"password invalid."}
Oh thank you.. very neat.
Even though this is closed, there might be a better solution, by overriding some of Doorkeeper's methods in an own helper. This is how I do it:
module Doorkeeper
module Helpers::Controller
alias_method :old, :get_error_response_from_exception
def get_error_response_from_exception(exception)
error_name = case exception
when Errors::OwnError
:own_error
end
if error_name
OAuth::ErrorResponse.new name: error_name, state: params[:state]
else
old exception
end
end
end
module Errors
class OwnError < DoorkeeperError
end
end
end
Put all this under lib/doorkeeper/helpers/doorkeeper_helper.rb and require it in your doorkeeper initializer. Don't forget to add an error message under the specified key in your doorkeeper locales.
Exactly what i was looking for @checkbutton. I digged into the code source and was planning to craft it but being lazy is nice as well.
Most helpful comment
I have implement that by override tokens_controller