Overriding Devise 401 Error Response in Ruby on Rails
Hello, folks! Today, I’m going to talk about how to override the Devise 401 error response when you have both views and endpoints in the same Ruby on Rails app. First of all, I’d like to present my problem and discuss the solution. If you have a different solution, please share it with me.
I have a Devise method in my User model:
devise :registerable,
:recoverable, :rememberable, :lockable, :trackable,
:omniauthable
def active_for_authentication?
super and is_active?
end
The method checks whether the user is active or not. If the user is active, Devise doesn’t allow to creation session.
I have a Session controller:
class Api::V2::SessionsController < Devise::SessionsController
respond_to :json
def create
#your code
end
end
We override the create method in Api::V2::SessionsController from Devise::SessionsController. But we can’t override active_for_authentication? method’s response key or value. Normally the response is like the below:
{
"error": "Your account is not activated yet."
}
The above response is not the type I wanted. So I have to override it like below:
{
"success": false,
"status": 401,
"message": "Your account is not activated yet.",
"errors": [
{
"field_name": "inactive_user",
"messages": [
"Your account is not activated yet."
]
}
]
}
There are 2 steps to fix it
- Create a new concern
class CustomFailureApp < Devise::FailureApp
def http_auth_body
if request.controller_class == Api::V2::SessionsController && request.format == :json
json_error_response
else
super
end
end
def json_error_response
self.status = 401
self.content_type = "application/json"
self.response_body =
{
success: false,
status: 401,
message: I18n.t('devise.failure.inactive'),
"errors": [
{
"field_name": "inactive_user",
"messages": [
I18n.t('devise.failure.inactive')
]
}
]
}.to_json
end
end
2. Add a devise config
config.warden do |manager|
manager.failure_app = CustomAuthFailure
end
The Links:
https://gist.github.com/emilsoman/5604254#file-custom_auth_failure_app-rb
https://stackoverflow.com/questions/7297183/custom-devise-401-unauthorized-response/35299936#35299936
https://github.com/heartcombo/devise/blob/main/app/controllers/devise/sessions_controller.rb
https://github.com/heartcombo/devise/blob/main/lib/devise/failure_app.rb#L197