Reputation: 395
I have got a Rails 5.2 app in API mode. If a request is supplied with correct Basic Authentication credentials, expected JSON data { status: true, data: 'test_user_data' }
will be rendered.
users_controller.rb
class Api::UsersController < ApplicationController
before_action :basic_authenticate
def get_user_info
render json: { status: true, data: 'test_user_data' }
end
private
def basic_authenticate
authenticate_or_request_with_http_basic do |username, password|
username == 'test_name' && password == 'test_password'
end
end
end
application_controller.rb
class ApplicationController < ActionController::API
include ActionController::HttpAuthentication::Basic::ControllerMethods
end
However, if Basic Authentication fails, only a plain text HTTP Basic: Access denied.
is rendered.
What I would like to do is to render error messages in JSON in case of authentication failure, something like { status: false, message: 'basic authentication failed'}
.
What is the proper way to fix it?
Upvotes: 0
Views: 664
Reputation: 106882
authenticate_or_request_with_http_basic
takes an optional message
parameter (which is, unfortunately, the second in the parameter list, therefore the "Application"
for the first parameter).
In Rails 5 just change your code to:
def basic_authenticate
message = { status: false, message: 'basic authentication failed' }.to_json
authenticate_or_request_with_http_basic("Application", message) do |username, password|
username == 'test_name' && password == 'test_password'
end
end
The implementation has changed in Rails 6 and therefore in Rails 6 the most basic implementation would look like this:
def basic_authenticate
message = { status: false, message: 'basic authentication failed' }.to_json
authenticate_or_request_with_http_basic(nil, message) do |username, password|
username == 'test_name' && password == 'test_password'
end
end
Upvotes: 2
Reputation: 736
Use rescue from in your application_controller.rb
like below
rescue_from User::NotAuthorized, with: :deny_access # self defined exception
def deny_access
render json: { status: false, message: 'basic authentication failed'}
end
Upvotes: 0