登录失败后设计重定向
Posted
技术标签:
【中文标题】登录失败后设计重定向【英文标题】:Devise redirect after login fail 【发布时间】:2011-08-15 12:20:26 【问题描述】:我发现的所有问题都与使用助手成功登录有关
after_sign_in_path_for(resource)
我在网站的索引中有一个登录表单,当登录失败时,它会重定向到“users/sign_in”
但是当登录失败时如何重定向到我的“site#index”?
【问题讨论】:
【参考方案1】:在您的 lib 目录中创建一个 custom_failure.rb,其中:
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)
别忘了重启你的服务器。
我认为没有更简单的方法可以做到这一点。祝你好运。
【讨论】:
这不起作用。我知道这是来自设计 wiki 的常用答案。respond
方法的内容可以重构为http_auth? ? http_auth : redirect
。效果很好!
这对我不起作用,它仍然重定向回登录
这对我使用 Devise 3.2.4 有效。确保在包含或更改任何这些文件时重新启动服务器。你可能会收到这样的错误:NameError - undefined local variable or method 'login' for #<CustomFailure:0x007ffc4aeb9328>
如果你不这样做。
在带有 Devise 4.3.0 的 Rails 5 中运行良好。只需将文件 custom_failure.rb 放入 /app/models/concerns 并跳过 autoload_paths 步骤 #3。谢谢@Marcao,你节省了我的时间!【参考方案2】:
如果您使用自己的SessionsController
,您可以重新分配auth_options
的:recall
值以在运行warden.authenticate!(auth_options)
之前调用您想要的controller#method
,例如:
在 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 并修改配置。
【讨论】:
这会将 url 修改为 users/sign_in【参考方案3】:这就是设计 3.1.0 所发生的情况
Started POST "/users/sign_in"
Processing by Devise::SessionsController#create
Completed 401 Unauthorized
Processing by Devise::SessionsController#new
由于 gems/devise-3.1.0/app/controllers/devise/sessions_controller.rb 末尾定义的 auth_options 而调用 new
您应该重新定义创建操作中使用的 auth_options。我在我的 Rails 应用程序的 app/controllers/devise/sessions_controller.rb 中复制了控制器,并像这样替换了 auth_options 方法
def auth_options
:scope => resource_name, :recall => "Home#new"
end
它成功了,但 url 仍然是 /users/sign_in
我也会尝试解决这个问题。
【讨论】:
我现在正在设计 3.2.2。 Marcao 的解决方案非常有效。无需复制和修补设计控制器或设置 auth_options。【参考方案4】:您可以更改默认登录路径。
查看https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes
【讨论】:
谢谢@MikeH,我试过了。 devise_for :users do get 'users', :to => 'site#index', :as => :user_root # Rails 3 end 在所有情况下都可以完美重定向到我的索引,登录时除外失败。在这种情况下,它重定向到 user/sign_in,我想重定向到“site#index”。 嗯。当登录失败时,设计的失败应用程序将重定向到 new_#scope_session_path (在您的情况下为 new_user_session_path)。当您执行 rake routes 时,会为此资源路径显示什么控制器/操作? 你找到答案了吗?我还在找……【参考方案5】:详细说明 Marcao 的答案,我强烈建议在您的 CustomFailure 响应方法中放置一些 debugger,以便更好地了解正在发生的事情。
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
。
但是,如果您希望返回 http_auth 方法中定义的标准 401 状态,则需要验证您的 respond
方法代码是否返回 http_auth
。
因此,值得您花时间研究http_auth?
的定义
特别要注意:request.xhr?
方法,它将为 json 请求返回 0(回想一下,在 ruby 中 0 实际上计算为 true)
def http_auth?
if request.xhr?
Devise.http_authenticatable_on_xhr
else
!(request_format && is_navigational_format?)
end
end
也许检查您的初始化程序/设计文件中的config.http_authenticatable_on_xhr
或config.navigational_formats
以控制您想要的响应。这种配置确实会影响 Devise 返回的内容,并且由于它在后台所做的工作,通常会导致意外行为。
【讨论】:
以上是关于登录失败后设计重定向的主要内容,如果未能解决你的问题,请参考以下文章
Grails Spring Security登录失败未重定向到登录视图