Объявление пользовательского действия при сбое для надзирателя не работает

В настоящее время в моем диспетчере надзирателей у нас есть пользовательское приложение для отказа.

    Rails.configuration.middleware.use Warden::Manager do |manager|
      manager.default_strategies :password
      manager.failure_app = lambda { |env| SessionsController.action(:new).call(env) }
    end

Однако для одной из моих стратегий я хочу использовать другое действие при сбое, поэтому я попытался объявить настраиваемое действие при сбое как таковое:

 def authenticate!
   email =  params["email"] || params['session']['email']
   pw =  params["password"] || params['session']['password']
   user = User.find_by_email email
   if user && user.authenticate_and_activated(pw)
     success! user
   else
     throw(:warden, :stuff => "foo", :action => :failure)   
   end
 end

и даже в моем действии контроллера:

 def sign_in
   @user = warden.authenticate! :action => :failure
   ...
 end

и вот мое действие при отказе:

def failure        
  warden.custom_failure!
  render :json => {:success => false, :errors => ["Login Failed"]}
 end

Но проблема в том, что он, похоже, игнорирует это и вызывает только действие, объявленное в моем менеджере. Кто-нибудь знает, что я могу делать неправильно?


person JustNeph    schedule 20.03.2013    source источник


Ответы (1)


Я смог найти свое решение с идеей, предложенной JonRowe по вопросам Warden на Github (https://github.com/hassox/warden/issues/73)

С его предложением изменить мою лямбду я смог изменить конфигурацию своего менеджера надзирателей следующим образом:

Rails.configuration.middleware.use Warden::Manager do |manager|
  manager.default_strategies :password
  manager.failure_app = lambda { |env| 
    failure_action = env["warden.options"][:action].to_sym
    SessionsController.action(failure_action).call(env) 
  }
end

Это подняло действие отказа, которое я передал в него. Кажется, он хранится в хеше «warden.options» под действием.

person JustNeph    schedule 24.03.2013
comment
Мне удалось заменить жестко заданный SessionsController ссылкой на используемый контроллер. Это может сделать это решение немного более гибким, если у вас есть несколько контроллеров сеансов. env["action_controller.instance"].class.action(failure_action).call(env) - person Ian Shields; 21.09.2020