Rails authenticity_token в форме 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" />

Значок csrf необходим для js-вызовов. Но почему маркер формы отличается от токена csrf? Какой из двух токенов используется при отправке формы?

+8
10 авг. '16 в 10:35
источник поделиться
1 ответ

Я сделал несколько исследований, чтобы ответить на ваш вопрос, и вот результаты.

Прежде всего, рассмотрим эту часть:

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

Эта часть создается методом csrf_meta_tags. Из исходного кода видно, что:

  • Значение "content" атрибута <meta name="csrf-param" /> взято из request_forgery_protection_token, и по умолчанию это :authenticity_token.

  • Значение "content" атрибута <meta name="csrf-token" /> взято из метода form_authenticity_token, где токен либо берется из сеанса, или сгенерировано.

Теперь рассмотрим эту часть:

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

Из источника видно, что:

  • Этот скрытый ввод возвращается методом extra_tags_for_form.
  • Внутри extra_tags_for_form вызывается метод token_tag.
  • token_tag метод принимает токен в качестве аргумента.
  • token аргумент token_tag ранее извлекается из аргумента options метода form_tag в html_options_for_form.

Итак, если вы не вручную установили authenticity_token param в options в свой пользовательский токен и не соответствовали условиям, которые приводят к установке значения token в значение false (будет указано ниже), token_tag метод получит nil и вызовет тот же метод form_authenticity_token, который используется для создания тега <meta name="csrf-token" />. Кстати, для заполнения атрибута ввода name он также использует request_forgery_protection_token, который используется при генерации тэга <meta name="csrf-param" />.

И поскольку это все происходит во время одного и того же запроса, вызов метода form_authenticity_token должен возвращать тот же результат в обоих случаях.

Какой из двух токенов используется при отправке формы?

При отправке формы будет использоваться токен из скрытого ввода.

Также может использоваться токен из <meta />, но только если все ниже условия (которые делают аргумент token token_tag будет установлено значение false):

  • :remote => true следует передать в options из form_tag.
  • embed_authenticity_token_in_remote_forms config установлен в значение false.
  • authenticity_token не передан в options.

Но почему маркер формы отличается от токена csrf?

Что касается этого вопроса, возможно, эта проблема возникает из-за кэширования. Или, возможно, если вы используете драгоценный камень Turbolinks, это может вызвать эту проблему (вы можете проверить это, если вы полностью обновите страницу и сравните токены еще раз). Для получения дополнительной информации о проблеме с Turbolinks, проверьте этот вопрос.

0
01 авг. '17 в 17:05
источник

Посмотрите другие вопросы по меткам или Задайте вопрос