Rails 4 authenticity_token使用多个服务器

时间:2015-06-25 11:18:27

标签: ruby-on-rails session cookies

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

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

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

因此,如果我从服务器1生成authenticity_token然后下一个请求(表单中的POST)命中服务器2,那么请求将被拒绝抛出错误或轨道异常。

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

谢谢!

2 个答案:

答案 0 :(得分:0)

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

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

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

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

答案 1 :(得分:0)

在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)