【问题标题】:Devise warden 401 Unauthorized when wrong credentials错误凭据时设计守望者 401 未经授权
【发布时间】:2013-01-10 09:10:26
【问题描述】:

我有一个非常标准的 Devise 登录程序:

查看:

resource_name, :url => session_path(resource_name)) 做 |f| %>
<%= f.input :password, input_html: {class: "span6"} %>

<% if devise_mapping.rememberable? -%>
    <p><%= f.check_box :remember_me %>&nbsp;&nbsp;&nbsp;Remember me</p>
<% end -%>

<input type="hidden" name="after_sign_in_page" value="<%=@after_sign_in_page%>">
<p><%= f.submit "Sign in", class: "btn btn-success" %></p>

我刚刚创建了一个会话控制器来小写电子邮件:

class SessionsController < Devise::SessionsController

  def create
    params[:user][:email].downcase!
    super
    logger.debug "Errors: #{resource.errors}"
  end

使用良好凭据登录会很好。

使用错误的凭据,它会重定向到带有此日志的登录页面:

Started POST "/users/sign_in" for 127.0.0.1 at 2013-01-10 09:59:44 +0100
Processing by SessionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"8eytQkr20JOOOdDvpCWakbmUzNoaHMxK9/BSEVxETik=", "user"=>{"email"=>"nicolas@demoreau.be", "password"=>"[FILTERED]", "remember_me"=>"0"}, "after_sign_in_page"=>"", "commit"=>"Sign in"}
Time zone: (GMT+00:00) UTC, current area: , user to register: , current controller: sessions
Completed 401 Unauthorized in 69ms
Processing by SessionsController#new as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"8eytQkr20JOOOdDvpCWakbmUzNoaHMxK9/BSEVxETik=", "user"=>{"email"=>"nicolas@demoreau.be", "password"=>"[FILTERED]", "remember_me"=>"0"}, "after_sign_in_page"=>"", "commit"=>"Sign in"}
  Rendered devise/sessions/_new.html.erb (17.8ms)
  Rendered devise/sessions/new.html.erb within layouts/application (19.7ms)
  Rendered layouts/_header.html.erb (66.1ms)
Completed 200 OK in 173ms (Views: 98.3ms | ActiveRecord: 0.9ms)

显然 401 是 Warden 放弃的,但我不知道为什么。 用户被正确重定向回登录页面,但没有显示错误消息(这是正常的,因为它们被重定向清除了)

我做错了什么?

谢谢!

编辑 1:

现在,我找到了一个快速破解方法。我在 SessionsController#new 中添加了这个

if params[:user]
  flash[:alert] = "Incorrect login or password"
end

不是很优雅,但至少,我有一些东西。

【问题讨论】:

    标签: ruby-on-rails devise warden


    【解决方案1】:

    首先,让我建议您不要覆盖 Devise 控制器:

    1. 在这种情况下,Devise 负责将电子邮件转换为 适合你,所以真的没有必要覆盖 create 方法。
    2. 如果您坚持使用 标准。

    另外,Devise 应该自动设置一个 flash 错误,确保你在你的视图中显示它。

    状态码 401 只是对未授权请求的标准响应。

    401 Unauthorized 与 403 Forbidden 类似,但专门用于使用 当需要身份验证并且已失败或尚未验证时 提供

    http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

    您绝对应该考虑放弃您的自定义控制器,

    干杯

    【讨论】:

    【解决方案2】:

    不会设置您的 Flash 消息,因为 Devise::SessionsController#create 调用warden 进行身份验证,如果失败,将调用Devise::FailureApp。您的控制器从不处理故障情况。

    如果您想要自定义消息,您可以为此自定义失败应用程序,Devise wiki 中有一些文章解释了如何做到这一点。

    但一般而言,您可以通过 I18n 自定义失败消息,并且可能有更好的方法来实现您想要的,而无需覆盖 Devise 控制器。

    【讨论】:

    • 您好何塞,非常感谢您的帮助!我不知道你在哪里找到所有这些能量。经过几个小时和几个小时的战斗,我终于发现了我没有预料到的有罪:我在 ApplicationController 中添加了一个额外的检查来重置会话,如果 current_user 为 nil 并且这显然与 Devise 冲突......配置没问题...啊!
    【解决方案3】:

    我同意 jassa,只需更新您的 Devise 版本(使用bundle update devise)。

    Devise 中已经存在不区分大小写的电子邮件,只需确保您有此配置:

    # devise.rb
    Devise.setup do |config|
      config.case_insensitive_keys = [:email ]
    end
    

    在任何情况下,由于您似乎缺少一些闪存消息和此配置,因此您最好重新运行生成器:

    rails generate devise:install
    

    然后你应该让 Devise 覆盖一些文件,只要确保你先备份你的。

    【讨论】:

    • 您好,很抱歉回复晚了。关于不敏感的电子邮件,我完全同意你的看法,但这不是我的问题(也不是它的原因)。问题是关于 flash[:messages]。我试图重新生成安装。它没有帮助......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 2015-04-19
    • 1970-01-01
    • 1970-01-01
    • 2017-12-20
    • 1970-01-01
    • 2014-03-10
    相关资源
    最近更新 更多