【问题标题】:Rails 4 authenticity_token using multiple serversRails 4 authentication_token 使用多个服务器
【发布时间】:2015-06-25 11:18:27
【问题描述】:

关于 Rails 中使用 CookieStore 的会话,如果我有两台服务器具有相同的 Rails 应用程序并且配置方式相同(哈希和配置相同),我知道如果一个用户点击第一台服务器并启动会话,那么如果下一个请求到达第二台服务器,则应用程序将正常工作。现在没关系。

但是,关于表单和authenticity_token,你如何处理(防止CSRF)?

假设我有一个 Cookie 哈希会话(使用 CookieStore),它使用客户端(浏览器)中的 Cookie 存储。所以服务器端根本不使用会话。

因此,如果我从服务器 1 生成一个authenticity_token,然后下一个请求(来自表单的 POST)到达服务器 2,该请求将被拒绝并抛出错误或 rails 异常。

你如何处理这个问题?共享内存中的authentity_tokens或使用“中间件”软件,例如Redis键值存储,以便每个服务器都可以验证authentity_tokens?

谢谢!

【问题讨论】:

  • 您是否真的尝试过并收到错误,或者这只是一个假设? CSRF 令牌基于当前会话,并且由于会话信息存储在 cookie 中,它应该可以跨多个服务器工作。

标签: ruby-on-rails session cookies


【解决方案1】:

从 Rails 版本 4 开始,我看到:

“如果您设置了 secret_key_base,您的 cookie 将被加密。这比签名 cookie 更进一步,因为加密的 cookie 不能被用户更改或读取。这是从 Rails 4 开始的默认设置。”

(CookieStore 的文档,http://api.rubyonrails.org/classes/ActionDispatch/Session/CookieStore.html)。

所以我认为authentity_token将在会话(Cookie端)中设置,然后将作为隐藏字段发送到表单,因此下一个请求将独立于服务器(server1,server2等)进行验证)。因此,通过加密,客户端用户将看不到authentity_token。如果没有加密,它可以被看到并且可能是一个安全问题。

【讨论】:

    【解决方案2】:

    在 UsersController 中你可以使用:

    sign_in(@user, :bypass => true)
    

    来自Devise::Controllers::SignInOut

    在文档中我们可以阅读:

    登录已通过身份验证的用户。此帮助器对于在注册后登录用户很有用。

    为 sign_in 提供的所有选项都被传递给warden 中的 set_user 方法。 唯一的例外是 :bypass 选项,它绕过warden回调并将用户直接存储在会话中。此选项在用户已经登录但我们想在会话中刷新凭据的情况下很有用。

    例子:

    sign_in :user, @user                      
    sign_in(scope, resource)
    sign_in @user                             
    sign_in(resource)
    sign_in @user, event: :authentication  
    sign_in(resource, options)
    sign_in @user, store: false            
    sign_in(resource, options)
    sign_in @user, bypass: true            
    sign_in(resource, options)
    

    【讨论】:

      猜你喜欢
      • 2014-05-26
      • 2018-10-29
      • 2015-01-30
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多