[英]Devise redirect after login fail
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”?
Create a custom_failure.rb in your lib directory, with:在您的 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
In you Devise initializer, include:在您的 Devise 初始化程序中,包括:
config.warden do |manager| manager.failure_app = CustomFailure end
Make sure Rails is loadin your lib files, in your application.rb:确保 Rails 在你的 application.rb 中加载你的 lib 文件:
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.
祝你好运。
If you use your own SessionsController
, you can re-assign the :recall
value of auth_options
to recall the controller#method
you want before running warden.authenticate!(auth_options)
, for example:如果您使用自己的
SessionsController
,您可以重新分配auth_options
的:recall
值以在运行warden.authenticate!(auth_options)
之前调用您想要的controller#method
#method,例如:
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 并修改配置。
This is what happens with devise 3.1.0这就是 devise 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.您应该重新定义 create 操作中使用的 auth_options。 I copied the controller in app/controllers/devise/sessions_controller.rb of my Rails application and replaced the auth_options method like this
我在我的 Rails 应用程序的 app/controllers/devise/sessions_controller.rb 中复制了 controller 并像这样替换了 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.我也会尝试解决这个问题。
You can change the default sign_in path.您可以更改默认登录路径。
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
Elaborating on Marcao's answer, I highly recommend placing some debugger in 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 Code for the respond method it is super easy to understand what is going on.如果您查看响应方法的FailureApp Devise 源代码,很容易理解发生了什么。
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 respond
code conditionals eventually return redirect
.因此,例如,为了返回 redirect_url 您需要确保您的
respond
代码条件最终返回redirect
。
However if you want to maybe return a standard 401 status as defined in the http_auth method, you want to verify that your respond
method 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?
因此,值得您花时间研究一下
http_auth?
In particular, note the: request.xhr?
特别要注意:
request.xhr?
method, which will return 0 for json requests (recall that 0 actually evaluates to true in ruby)方法,它将为 json 请求返回 0(回想一下 0 实际上在 ruby 中计算为 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_xhr
or config.navigational_formats
in order to control the response that you want.并且可能检查您的初始化程序/设计文件中的
config.http_authenticatable_on_xhr
或config.navigational_formats
以控制您想要的响应。 This configuration can really affect what Devise returns and can often lead to unexpected behavior due to what it does here under the hood.这种配置确实会影响 Devise 返回的内容,并且由于它在后台所做的事情,通常会导致意外行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.