Rails authenticity_token 在表单上与 csrf 令牌

Rails authenticity_token on a form vs csrf token

在 rails 4 个应用程序的同一页面上,我有一个

在头部:

<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="some_token" />

正文及以下:

<form action="/someaction" method="post">
<input name="utf8" type="hidden" value="&#x2713;" />
<input type="hidden" name="_method" value="patch" />
<input type="hidden" name="authenticity_token" value="another_token" />

js 调用需要 csrf 令牌。但为什么表单令牌与 csrf 令牌不同?提交表单时使用了这两个标记中的哪一个?

我做了一些研究来回答你的问题,这里是结果。

首先我们来看这部分:

<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="some_token" />

这部分是由方法csrf_meta_tags生成的。从源码中我们可以看出:

  1. "content" <meta name="csrf-param" /> 的属性值取自 request_forgery_protection_token,默认情况下为 :authenticity_token.

  2. "content" <meta name="csrf-token" /> 的属性值取自 form_authenticity_token 方法,其中令牌要么取自会话,要么生成。

现在让我们看看这部分:

<input type="hidden" name="authenticity_token" value="another_token" />

从源码中我们可以看出:

  1. 这个隐藏的输入是 return 通过 extra_tags_for_form 方法编辑的。
  2. extra_tags_for_form 内部调用 token_tag 方法。
  3. token_tag 方法将令牌作为参数。
  4. token token_tag 的参数先前是从 form_tag method in html_options_for_form 方法的 options 参数中提取的。

因此,如果您没有手动将 options 中的 authenticity_token 参数设置为您的自定义令牌,并且不满足导致将 token 值设置为 false 的条件(将将在下面提到),token_tag 方法将接收 nil 并调用用于创建 <meta name="csrf-token" /> 标记的相同 form_authenticity_token 方法。顺便说一句,为了填充输入的 name 属性,它还使用 request_forgery_protection_token,即在 <meta name="csrf-param" /> 标记生成发生时使用。

因为这一切都发生在同一个请求中,所以调用 form_authenticity_token 方法在两种情况下应该 return 相同的结果。

Which of the two tokens is used on form submission?

提交表单时将使用来自隐藏输入的令牌。

来自 <meta /> 的令牌也可以使用,但前提是以下所有 conditions(使 token_tag 方法的 token 参数设置为 false)才会遇见:

  1. :remote => true 应在 form_tagoptions 中传递。
  2. embed_authenticity_token_in_remote_forms 配置设置为 false。
  3. authenticity_token 未在 options 中传递。

But why is the form token different from the csrf token?

至于这个问题,可能是缓存的问题。或者,如果您使用 Turbolinks gem,可能会导致此问题(如果您完全刷新页面并再次比较令牌,则可以检查此问题)。有关 Turbolinks 问题的更多信息,请查看 this question

这可能与我留下答案的另一个问题有关: