Подтвердить что ты не робот

Создание форм вручную в Symfony2, но по-прежнему использовать CSRF и isValid()

Хорошо, я так сильно искал Google, но все, что я нашел, говорит о формах Symfony в контексте обычной обработки формы Symfony (например, form_widget(), создавая класс FormType и т.д.). У меня много таких форм в моем проекте Symfony, они отлично работают.

НО:

У меня также есть довольно сложные формы AJAX, которые я хотел бы создать вручную (используя простой старый HTML и JS). Я все еще хочу использовать возможности проверки Symfony Form и защиту CSRF. Однако по какой-то причине я не могу заставить CSRF работать при использовании isValid() для вручную созданных форм.

Это пример того, что я пытаюсь выполнить:

На моем контроллере я установил _token:

$_token = $this->get('form.csrf_provider')->generateCsrfToken('form');

По-моему (созданная форма вручную) (получение _token с моего контроллера представления):

<html>
  <form method="post">
    <input type="hidden" name="form[_token]" value="{{ _token }}">
    <input type="hidden" name="form[id]" value="1">
    <input type="submit" value="Submit">
  </form>
</html>

В моем контроллере действий (когда представленная форма, я ПЫТАЮСЬ сделать следующее):

//Create form (for validation purposes)
$form = $this->get('form.factory')
  ->createBuilder('form', array('id' => $request->get('id')))
  ->add('id', 'hidden')
  ->getForm();

//Bind form
$form->bind($request)

//Validate form
if($form->isValid()) {
  //... save data
}

//Return response...

По какой-то причине я не могу заставить isValid() работать, я подозреваю, что мой _token не используется должным образом, но я не понимаю, почему. Кто-нибудь на самом деле сделал вручную работу с компонентами Symfony? Есть ли у кого-нибудь предложения о том, как сделать эту работу?

В принципе, я хочу выполнить следующее:

  • Вручную создайте HTML-форму (с защитой CSFR и без функций виджета формы TWIG)

  • Используйте функцию формы Symfony для проверки этой формы

Спасибо.

4b9b3361

Ответ 1

Я думаю, что вы не согласны с намерением здесь (аргумент передан вашему провайдеру CSRF). Я попытался создать форму, как вы писали выше, и сломал генератор токена. Значение было unknown.

Итак, попробуйте передать unknown вместо form на ваш вызов generateCsrfToken и, надеюсь, он должен работать.;)

EDIT:

Я только что закончил рыть, и теперь это имеет смысл.

Посмотрите на класс FormTypeCsrfExtension. По-видимому, это расширение по умолчанию, используемое для защиты маркеров CSRF. В строке #80 (может быть, это не так точно в вашем случае) существует метод setDefaultOptions, который обычно переопределяется в ваших типах форм. Во всяком случае, есть опции по умолчанию intention, которые имеют значение unknown == > того, которое мы видим здесь.

Я предполагаю, что вы можете легко переопределить эту опцию в своем собственном типе формы, просто передав intention и установив собственное значение (так же, как вы пройдете csrf_protection = > false, когда вы хотите полностью отключить защиту CSRF).

Ответ 2

Примечание: намерение больше не задано по умолчанию. Когда я проверил это в symfony 2.3, по умолчанию будет указано имя типа:

$options['intention'] ?: ($builder->getName() ?: get_class($builder->getType()->getInnerType()))

Было бы хорошо, если бы был какой-то программный способ получить намерение, которое используется вместо того, чтобы полагаться на эти значения по умолчанию.

Ответ 3

Я видел, что это разрешено, но у меня тоже есть проблемы с формой, и я увидел там еще одну запись:

Symfony2 CSRF недействителен

И их решение кажется мне лучше, чем мой собственный токен:

Нет проблем с использованием {{form_widget (form)}} для создания вашей пользовательской формы. Все, что вам нужно сделать, это добавить _token следующим образом: {{form_widget (form._token)}}

Ответ 4

Мое решение с использованием Symfony 2.8:

в контроллере действий (при отправке формы):

    $theToken = $request->get('Token');

    //Token Verification   
    $isValidToken = $this->isCsrfTokenValid('your_intention', $theToken);
    if ($isValidToken === false)
    {
        // Error
    }

проверьте эту страницу, где я нашел информацию: http://api.symfony.com/2.8/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.html#method_isCsrfTokenValid