【问题标题】:How do rails authenticity tokens work? Further clarification neededRails 真实性令牌如何工作?需要进一步澄清
【发布时间】:2016-03-25 16:21:24
【问题描述】:

我正在阅读这篇描述 Rails 真实性令牌如何工作的 stackoverflow 评论:Understanding the Rails Authenticity Token

而评分最高的回应是这样开始的:

“当用户查看表单以创建、更新或销毁资源时,Rails 应用程序会创建一个随机的authentity_token,将此令牌存储在会话中,并将其放置在表单中的隐藏字段中。当用户提交表单,Rails 查找authenticity_token,将其与会话中存储的进行比较,如果匹配,则允许继续请求。”

这对我来说是一个抽象概念,但我想从具体意义上了解它是如何工作的,我想确切地了解这是如何发生的,所以我非常清楚它是如何工作的,所以我创建了一个新的 rails 应用程序并用只有一个字段name 搭建了一个User,然后我在动作内部的Users#create 顶部放置了一个binding.pry,这应该在用户提交表单后直接发生。在我添加了一个新的用户名之后,pry 会话就开始了,点击提交,它开始创建......所以我在我的网络浏览器中检查了我的应用程序的源代码,发现我的 rails 中的 csrf-token 内容值生成了 csrf 元标记与表单中隐藏的 authenticity token 值不匹配,并且如果在同一个 pry 会话期间检查 session.to_hash 属性并检查“_csrf_token”值,则两者都不匹配我得到的值。

然后我尝试在 Users#new 操作和 Users#create 操作中设置一个 pry,并在会话中记下“_csrf_token”值,并在我退出后将其与表单字段和元标记的值进行比较,我的应用程序在 Users#create 操作中移动到了 pry,但没有匹配项。这三个值似乎根本不匹配。

然而protect_from_forgery with: :exception 是在我的应用程序控制器中设置的,并且从我在评分最高的响应中读到的内容中,我期望在某个地方看到匹配的值。似乎没有什么匹配的。因此,我目前不知道什么 rails 与什么匹配以允许表单继续进行并保存数据。

评价最高的回复的作者还说,authenticity_token 存储在会话中,但我看到的只是_csrf_token(这些相同吗?)和session_id,正如我所说,它们不匹配任何东西。我没有看到任何匹配项。

如果 rails 将某些内容与我的表单字段中的值匹配,则它似乎不是“_csrf_token”的值,除非它在幕后将其转换为其他内容,然后将该值与隐藏的表单域什么的。我觉得我不明白发生了什么。

【问题讨论】:

  • 如果值不匹配,可能有一些编码正在进行,深入理解这些东西的最好方法是按照代码看看github.com/rails/rails/blob/v4.2.5/actionpack/lib/…,我没有t 完全遵循,但如果你这样做,你应该找到你正在寻找的东西。
  • 也许这是一个很好的阅读起点:guides.rubyonrails.org/security.html
  • @Alexander 我确实读过那个文件。你知道哪个部分回答了我要问的问题吗?因为我没有找到任何部分回答了我的问题。
  • 我链接到它,因为它在我曾经参加的 Code School 课程中被命名为进一步阅读的来源。我记得当他们谈到安全和会话时。但遗憾的是,我的记忆还不如回答你的问题。我不再订阅 Code School,否则我会搜索视频。但我确实记得,无论用户是否启用了 Javascript,行为都会有所不同,Rails 至少在这种情况下有一个备用方案。但是……我找到了另一个。也许这有帮助:railstutorial.org/book/…

标签: ruby-on-rails forms csrf-protection


【解决方案1】:

Rails 构建在 HTTP protocol 之上。

HTTP 是stateless,这意味着每个请求都必须被视为唯一的(每次都必须构建所有支持数据)。

为此,Rails 有session,它是存储在浏览器系统上的一系列“cookies”:

HTTP 是一种无状态协议。会话使其成为有状态的。

这些会话用于保存 Rails 使用的小型 sn-ps 数据,以便在每次请求时重建用户的“环境”。 Deviseuser_id 存储在 session 中,Rails 也在其中保存了大量其他数据。

--

因此,与 - 例如 - 一个游戏相反,您通过 TCP 等 有状态 协议拥有持续的数据流(一旦建立连接,它保持 em> 已建立),Rails 基本上会重新连接每个新请求。

此过程的一部分是表单提交

为防止由此引发的问题(IE 机器人/垃圾邮件发送者发送数百万个请求),Rails 使用 CSRF 将用户session 中的真实性令牌与网页上显示的真实性令牌“匹配”。

这基本上是说提交表单的用户是最初提出请求的用户,而不是通过代理或某些阴暗软件获得的机器人。

您最终会得到以下结果:

【讨论】:

  • 我必须感谢您,因为您的解释是解释“一般”如何工作的过程的绝佳方式,但(无意冒犯)它没有回答我的“具体”问题。我遇到的问题是:为什么我的元标记中的 csrf 令牌的内容、我的会话中的 csrf 令牌的值以及我表单隐藏部分中的真实性令牌的值都完全不同,如果 rails 不知何故将它们“匹配”在一起?
  • 我查看了 rails 应用程序内部,我目前确信 rails 以至少一种方式对令牌进行编码,并且可能在此文件的幕后以不止一种方式编码 (/actionpack-4.2.0 /lib/action_controller/metal/request_forgery_protection.rb) 这可以解释为什么它们看起来不同。不过我可能是错的。
  • 我的回答很笼统,因为你的问题很大。如果你想要具体的答案,你真的需要写具体的问题
  • 感谢所有的回答,我不是故意冒犯你的。
猜你喜欢
  • 2013-07-22
  • 1970-01-01
  • 2017-11-10
  • 2011-03-04
  • 2013-04-21
  • 2010-09-15
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
相关资源
最近更新 更多