2016-08-10 15 views
8

На этой же странице через рельсы 4 приложения У меня естьRails authenticity_token на форме против CSRF токена

в голове:

<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? Какой из двух токенов используется при подаче формы?

ответ

0

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

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

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

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

  1. «содержание» значение атрибута <meta name="csrf-param" /> берется из request_forgery_protection_token, и, по умолчанию, является :authenticity_token.

  2. значение атрибута «содержание» <meta name="csrf-token" /> взято из метода 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 аргумент для token_tag ранее извлечен из options аргумент form_tag метод в html_options_for_form метод.

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

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

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

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

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

  1. :remote => true должен быть передан в options из form_tag ,
  2. embed_authenticity_token_in_remote_forms config установлен в значение false.
  3. authenticity_token не был отправлен в options.

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

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

+0

Спасибо. Мне нужно некоторое время, чтобы посмотреть на ответ и понять его. – thebravoman

+0

@thebravoman Было ли это полезно? –

+0

Это было, мне просто нужно проверить несколько вещей с моим приложением, чтобы попытаться понять его полностью – thebravoman