【问题标题】:Rails authenticity_token on a form vs csrf token表单上的 Railsauthentity_token 与 csrf 令牌
【发布时间】:2016-12-16 16:40:11
【问题描述】:

在 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 令牌。但是为什么form token 和csrf token 不一样呢?提交表单时使用了这两个令牌中的哪一个?

【问题讨论】:

    标签: ruby-on-rails csrf authenticity-token


    【解决方案1】:

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

    首先我们来看看这部分:

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

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

    1. &lt;meta name="csrf-param" /&gt; 的“content”属性值取自request_forgery_protection_token,默认为:authenticity_token

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

    现在让我们看看这部分:

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

    从源码我们可以看出:

    1. 此隐藏输入由extra_tags_for_form 方法返回。
    2. extra_tags_for_form 内部调用token_tag 方法。
    3. token_tag 方法将令牌作为参数。
    4. token_tagtoken 参数之前是从 html_options_for_form 方法中的 form_tag 方法的 options 参数中提取的。

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

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

    这两个令牌中的哪一个用于表单提交?

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

    也可以使用来自&lt;meta /&gt; 的令牌,但前提是满足以下所有conditions(即使token_tag 方法的token 参数设置为false):

    1. :remote =&gt; true 应在 options 中传递 form_tag
    2. embed_authenticity_token_in_remote_forms 配置设置为 false。
    3. authenticity_token 未传入 options

    但是为什么form token 和csrf token 不一样呢?

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

    【讨论】:

    • Turbolinks +1。我遇到了 InvalidAuthenticityToken 问题,因为页面没有完全重新加载,并且页面中的令牌与 meta 标记中的令牌不同。
    【解决方案2】:

    这可能与另一个问题有关,我在其中留下了答案:

    CSRF token error occurs when using turbolinks with ruby on rails

    【讨论】:

      猜你喜欢
      • 2020-03-30
      • 2013-02-22
      • 2012-12-15
      • 2013-12-02
      • 2019-07-01
      • 2011-12-11
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      相关资源
      最近更新 更多