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

ger*_*rky 10 authentication cookies session ruby-on-rails devise

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

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

这是我到目前为止所知道的......

我知道cookies和会话.Cookie是存储在客户端的字符串,用于跨多个HTTP请求维护会话.

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

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

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

这是我的问题:

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

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

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

我知道我问了很多,但我相信这对像我这样不了解身份验证的人很有用,对于获得有关该主题的坚实基础非常有用.

Mik*_*ins 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 的主题,我还了解到您可以切换到使用不同类型的 Rails 会话存储。基于此,我听说系统将身份验证系统作为服务移出并使用身份验证令牌。什么是身份验证令牌以及它与会话 ID 有何不同?

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

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

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

我真的不认为除了使用 cookie 之外还有其他持久身份验证状态的选择(我想如果您感觉很陌生并且不太关心旧版浏览器支持,那么 HTML5 本地存储会起作用)。