关于使用CookieStore的Rails中的会话,如果我有两个服务器使用相同的Rails应用程序并以相同的方式配置(对于哈希和配置相同),我知道如果一个用户点击第一个服务器并启动一个会话,那么如果下一个请求到达第二个服务器,应用程序将正常工作。现在还可以。
但是,关于表单和authenticity_token,你如何处理这个问题(防止CSRF)?
假设我有一个Cookie哈希会话(使用CookieStore),它使用客户端(浏览器)中的Cookie存储。因此,根本没有在服务器端使用会话。
因此,如果我从服务器1生成authenticity_token然后下一个请求(表单中的POST)命中服务器2,那么请求将被拒绝抛出错误或轨道异常。
你是如何处理的?在内存中共享authenticity_tokens或使用“中间件”软件,例如Redis键值存储,以便每个服务器都可以验证authenticity_tokens?
谢谢!
答案 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)