Подтвердить что ты не робот

Принудительное перенаправление после входа в систему

Все вопросы, которые я нашел, связаны для успешного входа в систему с помощником after_sign_in_path_for(resource)

У меня есть форма входа в индекс сайта, и при неудачном входе в систему он перенаправляет на "users/sign_in"

Но как я могу перенаправить на свой "индекс сайта" при неудаче входа в систему?

4b9b3361

Ответ 1

  • Создайте custom_failure.rb в вашем каталоге lib, используя:

    class CustomFailure < Devise::FailureApp
      def redirect_url
        your_path
      end
    
      def respond
        if http_auth?
          http_auth
        else
          redirect
        end
      end
    end
    
  • В вы создаете инициализатор include:

      config.warden do |manager|
        manager.failure_app = CustomFailure
      end
    
  • Убедитесь, что Rails загружает ваши файлы lib в приложении application.rb:

    config.autoload_paths += %W(#{config.root}/lib)
    

Не забудьте перезагрузить сервер.

Я не думаю, что есть более простой способ сделать это. Удачи.

Ответ 2

Если вы используете свой собственный SessionsController, вы можете повторно назначить значение :recall auth_options для вызова controller#method, который вы хотите перед запуском warden.authenticate!(auth_options), например:

в приложении/контроллерах/users/sessions_controller.rb

class Users::SessionsController < Devise::SessionsController
  #...
  def create
    #...
    auth_options = { :recall => 'site#index', :scope => :user }
    resource = warden.authenticate!(auth_options)
    #...
  end
  #...
end

Таким образом, вам не нужно создавать настраиваемые FailureApp и изменять конфигурации.

Ответ 3

Вот что происходит с разработкой 3.1.0

Started POST "/users/sign_in"
Processing by Devise::SessionsController#create
Completed 401 Unauthorized
Processing by Devise::SessionsController#new

new получает вызов из-за auth_options, определенных в конце gems/devise-3.1.0/app/controllers/devise/sessions_controller.rb

Вы должны переопределить auth_options, используемые в действии create. Я скопировал контроллер в app/controller/devise/sessions_controller.rb моего приложения Rails и заменил метод auth_options, подобный этому

def auth_options
  { :scope => resource_name, :recall => "Home#new" }
end

Это трюк, но URL-адрес все еще /users/sign _in

Я попытаюсь это исправить.

Ответ 5

Разрабатывая ответ Marcao, я настоятельно рекомендую разместить отладчик в методе ответа CustomFailure, чтобы лучше понять, что происходит.

Class CustomFailure < Devise::FailureApp
  def respond
    binding.pry
    super
  end
end

Если вы посмотрите на FailureApp Devise Source Code для метода ответа, очень легко понять, что происходит.

def respond
  if http_auth?
    http_auth
  elsif warden_options[:recall]
    recall
  else
    redirect
  end
end

Так, например, чтобы вернуть redirect_url, вы должны убедиться, что ваши условные выражения respond в конечном итоге возвращают redirect.

Однако, если вы хотите, возможно, вернуть стандартный статус 401, определенный в методе http_auth, вы хотите проверить, что ваш метод respond code возвращает http_auth.

Таким образом, стоит взглянуть на определение http_auth? В частности, обратите внимание на метод request.xhr?, который будет возвращать 0 для json-запросов (напомним, что 0 фактически оценивает true в ruby)

def http_auth?
  if request.xhr?
    Devise.http_authenticatable_on_xhr
  else
    !(request_format && is_navigational_format?)
  end
end

И, возможно, проверьте свой файл инициализаций /devize для config.http_authenticatable_on_xhr или config.navigational_formats, чтобы контролировать ответ, который вы хотите. Эта конфигурация может действительно повлиять на то, что Devise возвращает и может часто приводить к неожиданному поведению из-за того, что она делает здесь под капотом.