Some time ago asked the same question.
Got no responses so not sure that I implemented in a best canonical way.
class Users::SessionsController < Devise::SessionsController
# prepend_before_filter :require_no_authentication, :only => [:failure]
layout "login"
# Have to reimplement :recall => "failure"
# for warden to redirect to some action that will return what I want
def create
logger.debug "Trying to create a new session..."
resource = warden.authenticate!(:scope => resource_name, :recall => "failure")
# set_flash_message :notice, :signed_in
sign_in_and_redirect(resource_name, resource)
end
# Mostly a copy of original source code.
# Needed only call render :json => ... in the end
def sign_in_and_redirect(resource_or_scope, resource=nil)
scope = Devise::Mapping.find_scope!(resource_or_scope)
resource ||= resource_or_scope
sign_in(scope, resource) unless warden.user(scope) == resource
render :json => { :success => true, :redirect => stored_location_for(scope) || after_sign_in_path_for(resource) }
end
def failure
render :json => {:success => false, :errors => {:reason => "Login failed. Try again"}}
end
end