多个选项卡注销会在后续登录时导致InvalidAuthenticityToken

时间:2014-09-11 18:22:57

标签: ruby-on-rails ruby authentication devise csrf

我有一个使用Devise进行身份验证的应用。登录字段位于主页上。如果我打开两个选项卡(选项卡A和选项卡B,然后手动注销每个选项卡(第一个选项卡A,然后选项卡B),然后返回选项卡A并尝试登录,我收到InvalidAuthenticityToken错误。

然后我可以回到标签B并尝试登录并获取错误。然后返回选项卡A并尝试登录并再次获取错误。这将无限期地发生,直到您在同一选项卡中收到InvalidAuthenticityToken错误后立即尝试登录选项卡。

我可以在ApplicationController中设置以下内容:

protect_from_forgery :with => :null_session

但是现在第一次登录尝试将返回主页,但没有指出您的登录失败的原因(您只是再次看到主页而不是InvalidAuthenticityToken错误页面)。如果您再次尝试登录(在同一选项卡上),则会成功。

我知道为什么会发生这种情况:会话正在重置注销,这会重置会话中的csrf_token。第二个选项卡重置该标记,但第一个选项卡仍然具有前一个标记。因此,当第一个标签提交表单时,csrf_token无效。

我可以在服务器端执行此操作吗?或者我将不得不做一些疯狂的解决方法,比如在你注销时在localStorage中设置一些东西,或者打开一个websocket,这样我就会在主页上通知另一个选项卡重置了CSRF令牌?

让一个打开多个标签的用户看起来似乎很少见并手动注销,但这只是模拟网站的实际行为:10分钟后自动将其记录下来。这实际上经常在我们的应用程序中发生。

1 个答案:

答案 0 :(得分:0)

Rails允许您使用rescue_from通过回调函数来挽救您选择的错误。

您可以在此处找到更多信息: https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html

解决了几乎相同的问题,我的Sessions控制器顶部看起来像这样

class SessionsController < ApplicationController

  rescue_from ::ActionController::InvalidAuthenticityToken, with: :redirect_home

和我在同一控制器中定义的回调类似

def redirect_home
   redirect_to root_url
end