当错误的凭证时,设计监狱长401未经授权

nde*_*eau 9 ruby-on-rails devise warden

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

视图:

resource_name,:url => session_path(resource_name))do | 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>
Run Code Online (Sandbox Code Playgroud)

我刚创建了一个sessioncontroller来封装电子邮件:

class SessionsController < Devise::SessionsController

  def create
    params[:user][:email].downcase!
    super
    logger.debug "Errors: #{resource.errors}"
  end
Run Code Online (Sandbox Code Playgroud)

具有良好凭据的登录很顺利.

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

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)
Run Code Online (Sandbox Code Playgroud)

显然401被Warden掉了但我无法弄明白为什么.用户被正确地重定向回登录页面,但没有显示错误消息(这是正常的,因为重定向消除了它们)

我究竟做错了什么?

谢谢!

编辑1:

现在,我发现了一个快速黑客.我在SessionsController #new中添加了这个

if params[:user]
  flash[:alert] = "Incorrect login or password"
end
Run Code Online (Sandbox Code Playgroud)

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

jas*_*ssa 5

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

  1. 在这种情况下,Devise负责将电子邮件转换为小写,因此实际上不需要覆盖该create方法.
  2. 如果您坚持标准,您的应用程序将无缝支持设计更新.

此外,Devise应自动设置闪光错误,确保您在视图中显示它.

状态代码401仅是未授权请求的标准响应.

401 Unauthorized与403 Forbidden类似,但专门用于需要验证且失败或尚未提供的情况

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

你一定要考虑放弃自定义控制器,

干杯

  • 此外,闪存消息很久以前就存在,"Devise使用带有闪存键的I18n闪存消息:通知和:警告." https://github.com/plataformatec/devise#i18n.确保您的视图指向与https://github.com/plataformatec/devise/blob/master/app/views/devise/sessions/new.html.erb相同的操作.最后,它必须是您的自定义代码的问题,也许您所做的不仅仅是您在此处显示的内容,请特别注意您执行的其他重定向.见http://bit.ly/V7larc (2认同)

Jos*_*lim 3

您的闪现消息不会被设置,因为Devise::SessionsController#create呼叫典狱长进行身份验证,如果失败,将呼叫Devise::FailureApp。您的控制器永远不会处理故障场景。

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

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

  • 嗨,何塞,非常感谢您的帮助!我不知道你从哪里找到这么多能量。经过几个小时的战斗后,我终于发现了我意想不到的地方:我在 ApplicationController 中添加了一个额外的检查,以在 current_user 为 nil 时重置会话,这显然与 Devise 冲突......其余的配置没问题...啊啊! (2认同)