#ruby-on-rails #redirect #login #devise
#ruby-on-rails #перенаправление #аутентификация #разработать
Вопрос:
Все найденные мной вопросы связаны с успешным входом в систему с помощью помощника after_sign_in_path_for(resource)
У меня есть форма входа в индекс сайта, и при сбое входа она перенаправляет на «users / sign_in»
Но как я могу перенаправить на свой site#index
, когда не удается войти в систему?
Ответ №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
-
В вашем инициализаторе разработки включите:
config.warden do |manager| manager.failure_app = CustomFailure end
-
Убедитесь, что Rails загружает ваши lib-файлы в ваше application.rb :
config.autoload_paths = %W(#{config.root}/lib)
Не забудьте перезапустить свой сервер.
Я не думаю, что есть более простой способ сделать это.
Комментарии:
1. Это не сработало. Я знаю, что это стандартный ответ из devise wiki.
2. Содержимое
respond
метода может быть переработано вhttp_auth? ? http_auth : redirect
. Отлично работает!3. У меня это не работает, оно по-прежнему перенаправляет обратно на логин
4. У меня это сработало с использованием Devise 3.2.4. При включении или изменении любого из этих файлов обязательно перезапускайте сервер. Вероятно, вы получите сообщение об ошибке, подобное этому:
NameError - undefined local variable or method 'login' for #<CustomFailure:0x007ffc4aeb9328>
если вы этого не сделаете.5. Отлично работает в Rails 5 с Devise 4.3.0. Просто поместите файл custom_failure.rb в /app /models /concerns и пропустите шаг autoload_paths #3. Спасибо @Marcao, ты сэкономил мое время!
Ответ №2:
Если вы используете свое собственное SessionsController
значение :recall
, вы можете повторно присвоить auth_options
значение controller#method
, чтобы вызвать warden.authenticate!(auth_options)
нужное перед запуском, например:
в app / controllers /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 и изменять конфигурации.
Комментарии:
1. Это изменяет URL-адрес на users / sign_in
Ответ №3:
Это то, что происходит с devise 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 / controllers / devise /sessions_controller.rb моего приложения Rails и заменил метод auth_options следующим образом
def auth_options
{ :scope => resource_name, :recall => "Home#new" }
end
Это делает свое дело, но URL по-прежнему остается /users/sign_in
Я постараюсь исправить и это.
Комментарии:
1. Сейчас я разрабатываю 3.2.2. Решение Marcao работает отлично. Нет необходимости копировать и исправлять контроллеры разработки или устанавливать auth_options.
Ответ №4:
Вы можете изменить путь входа по умолчанию.
Проверьте https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes
Комментарии:
1. Спасибо @MikeH, я попробовал это. devise_for : пользователи действительно получают ‘users’, :to => ‘site#index’, :as => :user_root # Rails 3 end Работает идеально, перенаправляя на мой индекс во всех случаях, за исключением сбоя входа в систему. В этом случае он перенаправляет на user / sign_in, и я хочу, чтобы меня перенаправили на «site # index».
2. Хм. При сбое входа в систему приложение devise с ошибкой перенаправляет на new_#{scope}_session_path (в вашем случае new_user_session_path). Когда вы выполняете rake routes , какой контроллер / действие отображается для этого пути к ресурсам?
3. Вы нашли ответ? Я все еще ищу это…
Ответ №5:
Развивая ответ Маркао, я настоятельно рекомендую поместить некоторый отладчик в ваш метод CustomFailure response, чтобы лучше понять, что происходит.
Class CustomFailure < Devise::FailureApp
def respond
binding.pry
super
end
end
Если вы посмотрите на исходный код FailureApp Devise для метода response, очень легко понять, что происходит.
def respond
if http_auth?
http_auth
elsif warden_options[:recall]
recall
else
redirect
end
end
Так, например, чтобы вернуть redirect_url, вы хотели бы убедиться, что ваши respond
условные обозначения кода в конечном итоге вернутся redirect
.
Однако, если вы хотите, возможно, вернуть стандартный статус 401, как определено в методе http_auth, вы хотите убедиться, что ваш respond
код метода возвращает 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 amp;amp; is_navigational_format?)
end
end
И, возможно, проверьте ваши инициализаторы / файл разработки на наличие config.http_authenticatable_on_xhr
or config.navigational_formats
, чтобы контролировать нужный вам ответ. Эта конфигурация действительно может повлиять на то, что возвращает Devise, и часто может приводить к неожиданному поведению из-за того, что он делает здесь, под капотом.