Ruby-on-rails 登录失败后设计重定向
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5832631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Devise redirect after login fail
提问by Juanjo
All the questions I've found are related for a successful login with the helper
after_sign_in_path_for(resource)
我发现的所有问题都与使用助手成功登录有关
after_sign_in_path_for(resource)
I have a login form in the index of the site, and when the login fails it redirects to "users/sign_in"
我在站点的索引中有一个登录表单,当登录失败时,它会重定向到“users/sign_in”
But how can I redirect to my "site#index" when the login fails?
但是,当登录失败时,如何重定向到我的“site#index”?
回答by Marco Antonio
Create a custom_failure.rb in your lib directory, with:
class CustomFailure < Devise::FailureApp def redirect_url your_path end def respond if http_auth? http_auth else redirect end end endIn you Devise initializer, include:
config.warden do |manager| manager.failure_app = CustomFailure endMake sure Rails is loadin your lib files, in your application.rb :
config.autoload_paths += %W(#{config.root}/lib)
在你的 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)
Don't forget to restart your server.
不要忘记重新启动服务器。
I don't think there's an easier way to do this. Good luck.
我认为没有更简单的方法可以做到这一点。祝你好运。
回答by Sibevin Wang
If you use your own SessionsController, you can re-assign the :recallvalue of auth_optionsto recall the controller#methodyou want before running warden.authenticate!(auth_options), for example:
如果您使用自己的SessionsController,则可以重新分配 的:recall值auth_options以controller#method在运行之前调用您想要的warden.authenticate!(auth_options),例如:
in app/controllers/users/sessions_controller.rb
在 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
With this way, you don't need to create the customized FailureApp and modify the configs.
通过这种方式,您无需创建自定义的FailureApp 并修改配置。
回答by pmontrasio
This is what happens with devise 3.1.0
这就是设计 3.1.0 发生的情况
Started POST "/users/sign_in"
Processing by Devise::SessionsController#create
Completed 401 Unauthorized
Processing by Devise::SessionsController#new
new gets called because of the auth_options defined at the end of gems/devise-3.1.0/app/controllers/devise/sessions_controller.rb
由于在 gems/devise-3.1.0/app/controllers/devise/sessions_controller.rb 末尾定义的 auth_options,new 被调用
You should redefine the auth_options used in the create action. I copied the controller in app/controllers/devise/sessions_controller.rb of my Rails application and replaced the auth_options method like this
您应该重新定义创建操作中使用的 auth_options。我在我的 Rails 应用程序的 app/controllers/devise/sessions_controller.rb 中复制了控制器,并像这样替换了 auth_options 方法
def auth_options
{ :scope => resource_name, :recall => "Home#new" }
end
It does the trick, but the url is still /users/sign_in
它可以解决问题,但 url 仍然是 /users/sign_in
I'll try to fix that as well.
我也会尝试解决这个问题。
回答by MikeH
You can change the default sign_in path.
您可以更改默认的 sign_in 路径。
Check out https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes
查看https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes
回答by AmitF
Elaborating on Marcao's answer, I highly recommend placing some debuggerin your CustomFailure respond method in order to better understand what is going on.
详细说明 Marcao 的答案,我强烈建议在您的 CustomFailure 响应方法中放置一些调试器,以便更好地了解发生了什么。
Class CustomFailure < Devise::FailureApp
def respond
binding.pry
super
end
end
If you look at the FailureApp Devise Source Codefor the respond method it is super easy to understand what is going on.
如果您查看响应方法的FailureApp 设计源代码,则非常容易理解发生了什么。
def respond
if http_auth?
http_auth
elsif warden_options[:recall]
recall
else
redirect
end
end
So for example in order to return a redirect_url you would want to make sure that your respondcode conditionals eventually return redirect.
因此,例如为了返回一个 redirect_url,您需要确保您的respond代码条件最终返回redirect.
However if you want to maybe return a standard 401 status as defined in the http_authmethod, you want to verify that your respondmethod code returns http_auth.
但是,如果您想返回http_auth方法中定义的标准 401 状态,您需要验证您的respond方法代码是否返回http_auth.
Thus it is worth your while to look into the definition of the http_auth?In particular, note the: request.xhr?method, which will return 0 for json requests (recall that 0 actually evaluates to true in ruby)
因此,值得您花时间研究 的定义,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
And maybe check your initializers/devise file for config.http_authenticatable_on_xhror config.navigational_formatsin order to control the response that you want. This configuration can really affect what Devise returns and can often lead to unexpected behavior due to what it does here under the hood.
也许检查您的初始化/色器件文件config.http_authenticatable_on_xhr或config.navigational_formats以控制所需的响应。这种配置确实会影响 Devise 返回的内容,并且由于它在幕后所做的事情,通常会导致意外行为。

