会话和cookie如何在Rails中运行?

时间:2015-03-21 12:50:45

标签: ruby-on-rails session authentication cookies devise

我一直在使用Devise来处理我的Rails应用程序上的身份验证,但从未真正理解它是如何工作的。因为Devise也使用Rails上的会话存储配置集,我假设这是一个关于使用Rails进行会话处理的问题。

基本上,我是一名新手。我已经阅读了一些关于身份验证的文章,但大多数都涉及对我来说没有多大意义的抽象库(他们谈论引擎,中间件等)。我真的在寻找较低级别的细节。

这是我目前所知道的......

我了解cookie和会话。 Cookie是存储在客户端的字符串,用于跨多个HTTP请求维护会话。

以下是我对身份验证的基本理解(如果我错了请纠正我):

  1. 当用户登录时,我们将SSL加密的请求发送到服务器。如果凭证有效,我们会在数据库(或任何其他数据存储)上保存一个名为session id的随机字符串作为与用户ID关联的有效会话ID。每次登录/注销用户时,此会话ID都会更改。

  2. 在我们的数据存储中保存该会话ID后,我们返回一个响应,要求浏览器设置一个带有会话ID的cookie。然后将该会话ID与用户ID一起发送,以便连续请求到域,直到它过期。对于每个请求,我们的服务器将检查标头上的会话ID,并验证该会话ID是否对该用户标识有效。如果是,则考虑用户进行身份验证。

  3. 以下是我的问题:

    1. 我已经读过默认从Rails 2开始,它现在使用CookieStore(而不是SessionStore)生成与SHA512(而不是会话ID)的会话哈希,并且所有这些都存储在cookie上,这意味着多个用户ID可以字面上具有相同的会话哈希,它只会工作正常。在我看来,这是一个非常危险的事情,使用存储在服务器上的单个密钥暴露大量哈希,并基于此密钥基于整个身份验证系统。是否存在使用散列而不是存储服务器端会话ID的真实世界大规模应用程序?

    2. 关于在服务器端存储活动会话ID的主题,我还读到您可以切换为Rails使用不同类型的会话存储。基于此,我听说系统将身份验证系统作为服务移动并使用auth令牌代替。什么是身份验证令牌,它与会话ID有什么不同?

    3. 似乎我可以继续猜测一个随机字符串(用于散列和服务器端会话)来获取现有会话。有没有办法防止这种情况发生?使用存储在cookie上的更多值是正常的吗? (例如用户名,真实姓名或甚至用于身份验证的其他哈希)

    4. 我知道我问了很多,但我相信这对像我这样不了解身份验证的人来说非常有用,对于为这个话题打下坚实的基础非常有用。

1 个答案:

答案 0 :(得分:3)

  

我从Rails 2开始默认读取它现在使用   CookieStore(而不是SessionStore)生成会话哈希   使用SHA512(而不是会话ID),所有这些都存储在一个   cookie意味着多个用户ID可以完全相同   会话哈希,它会工作正常。在我看来,这是   一个非常危险的事情,暴露了大量的哈希与   单个密钥存储在服务器上并基于您的整个   基于此密钥的身份验证系统。

是的,乍一看似乎很可怕,但我不确定危险究竟是什么。在Rails 4中,会话数据使用PBKBF2加密,然后使用您的会话密钥签名。此签名有助于检测加密会话的内容是否已被篡改,如果检测到篡改,服务器将拒绝该会话。

https://cowbell-labs.com/2013-04-10-decrypt-rails-4-session.html

如果某人获得了会话令牌(用于签署会话cookie)的访问权限,那么您手上的问题可能比最终用户冒充错误用户的问题要严重得多。

  

是否存在使用散列的真实世界大型应用程序   而不是存储服务器端会话ID?

老实说我不知道​​这个问题的答案,但我怀疑这是"默认"对于Rails意味着使用cookie会话存储的场所不止一些。

  

关于在服务器端存储活动会话ID的主题,我也是   请注意,您可以切换为使用不同类型的会话存储   轨。基于此,我听说系统移动身份验证   系统作为服务和使用auth令牌代替。什么是认证   令牌以及它与会话ID的区别?

我现在正在服务器上执行此操作 - 基本上,当用户进行身份验证时会生成随机哈希,并且该哈希值会在cookie中存储,加密和签名。 cookie哈希是服务器端数据存储区的密钥(在我的案例中是Redis,但它可以在关系数据库或内存缓存或任何你喜欢的内容中),实际的会话数据是映射到该密钥的存储服务器端。这会使客户手中的会话数据减少,因为人们可能会对其进行解密和分析,因此通常会更安全一些。

  

似乎我可以继续猜测一个随机字符串(对于两个散列都是如此)   抓住现有会话。有办法吗?   防止这种情况?使用存储在a上的更多值是否正常   曲奇饼? (例如用户名,真实姓名或者其他哈希值)   认证)

是的,你可以这样做,但这需要很长时间。您还需要猜测如何对新篡改的Cookie数据进行签名,以使其与服务器期望看到的内容相匹配,并使用相当大的密钥进行签名。

我真的不认为有更多选择来保持身份验证状态使用Cookie(我想如果你感觉异国情调并且不在乎,那么HTML5本地存储会有效传统浏览器支持)。