在超时后,Devise会使用重定向加倍401

时间:2013-10-12 00:55:07

标签: ruby-on-rails devise

我正在使用Rails 3.2.8和Devise 2.1.2。

如果会话在用户仍在应用中时超时,则下次用户点击应用中的内容时,会重定向到登录页面。但是,session[:user_return_to]的值通常不是我所期望的。在试图追查原因时,我发现Devise(或Warden)在收到401错误后正在做两个 GET

例如,如果用户正在编辑用户并在会话超时后单击更新,则日志如下所示:

Started PUT "/users/9f276de6-2175-11e3-b8ce-01413834ba1d" for 127.0.0.1 at 2013-10-11 16:43:36 -0700
Processing by UsersController#update as HTML
  Parameters: {"utf8"=>"?", "authenticity_token"=>"+JP3qXGyUEodmmlLQtpOJpxF8JuEg5sp4Iyjit784Ms=", "user"=>{"first_name"=>...}
  User Load (1.5ms)[0m  SELECT "users".* FROM "users" WHERE "users"."id" = '9b5f6b2e-40bc-31e3-b199-0141337836d6' LIMIT 1
Completed 401 Unauthorized in 9ms

Started GET "/users/9f276de6-2175-11e3-b8ce-01413834ba1d" for 127.0.0.1 at 2013-10-11 16:43:36 -0700
Processing by UsersController#show as HTML
  Parameters: {"id"=>"9f276de6-2175-11e3-b8ce-01413834ba1d"}
Completed 401 Unauthorized in 1ms

Started GET "/users/sign_in" for 127.0.0.1 at 2013-10-11 16:43:36 -0700
Processing by Devise::SessionsController#new as HTML
  Rendered devise/shared/_links.erb (7.2ms)
  Rendered devise/sessions/new.html.erb within layouts/application (21.8ms)
  Rendered layouts/_header.html.erb (7.5ms)
  Rendered layouts/_flash_messages.html.erb (0.1ms)
  Rendered layouts/_footer.html.erb (1.3ms)
Completed 200 OK in 174ms (Views: 171.8ms | ActiveRecord: 0.0ms)

第一个GET来自何处,即第一次身份验证失败后#show如何以及为何被调用?

如果我可以摆脱第一个GET,我希望session[:user_return_to]保持设置为/users/{:id}/edit路径,这可能是用户想要去的路径-authenticating。实际上,session[:user_return_to]设置为/users/{:id},因此当他们重新登录时,他们不会返回编辑模式。

顺便说一句,即使失败的请求是GET而不是PUT,我仍然会在转到登录页面之前看到额外的GET

1 个答案:

答案 0 :(得分:1)

所以基本上这是在这里报告的错误#2421:

store_location!() method gets wrong location after timeout

由修复#2427解决:

redirect user to the referrer if latest request was not GET after timeout

我可以说,在Devise 3.0.0之前,该修复程序尚未发布。

未来参考摘要

Devise 2.1.2在 device / failure_app.rb 中有此例程:

def redirect_url
  if warden_message == :timeout
    flash[:timedout] = true
    attempted_path || scope_path
  else
    scope_path
  end
end

使用该代码,{P}请求中设置了attempted_path,因此第一个重定向尝试对PUT使用的URI执行GET(在本例中为/users/{:id})。与GET一起使用时,该URI会调用#show操作。

此代码已更新为:

def redirect_url
  if warden_message == :timeout
    flash[:timedout] = true
    path = if request.get?
      attempted_path
    else
      request.referrer
    end
    path || scope_path
  else
    scope_path
  end
end

看起来在超时时仍然会进行双重定向,但对于PUT,它将使用request.referrer(在本例中为/users/{:id}/edit),因此session[:user_return_to]应该设置正确。

2013年10月25日更新我现在已升级到Devise 3.1.1。正如预期的那样,PUT在超时时仍会执行两次重定向,但session[:user_return_to]设置正确,因此用户在登录时返回引荐来源。