Everything I seem to find on this issue is out of date and/or doesn't work.
GOAL: When a user tries to sign in via JSON from a mobile application and the username or password is wrong, I would like Rails to return JSON data so the errors can be displayed on the app.
So far I have done the following:
class Users::SessionsController < Devise::SessionsController
# before_action :configure_sign_in_params, only: [:create]
skip_before_action :verify_authenticity_token
respond_to :json
# POST /resource/sign_in
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_flashing_format?
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, :location => after_sign_in_path_for(resource) do |format|
format.json {render :json => resource } # this code will get executed for json request
end
end
end
This works well on success, but I'm not sure what to do when it fails. Right now it returns an undefined method error:
undefined method `users_url' for #<Users::SessionsController:0x0000000195fa28>
Figured it out. CustomFailure never seemed to work, no matter how many things I tried. I was able to do this within the SessionsController via handle_failed_login:
class Users::SessionsController < Devise::SessionsController
# before_action :configure_sign_in_params, only: [:create]
after_filter :handle_failed_login, :only => :new
skip_before_action :verify_authenticity_token
respond_to :json
# POST /resource/sign_in
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_flashing_format?
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, :location => after_sign_in_path_for(resource) do |format|
format.json {render :json => resource } # this code will get executed for json request
end
end
private
def handle_failed_login
if failed_login?
render json: { success: false, errors: ["Login Credentials Failed"] }, status: 401
end
end
def failed_login?
(options = env["warden.options"]) && options[:action] == "unauthenticated"
end
end