在Symfony2中手动创建表单,但仍然使用其CSRF和isValid()功能

use*_*635 17 symfony

好吧,我用Google搜索了这一点,但我发现的所有内容都是在常规Symfony表单处理(例如form_widget(),创建FormType类等)的上下文中讨论Symfony表单.我的Symfony项目中有很多这样的表单,它们运行得很好.

但:

我还有一些非常复杂的AJAX表单,我想手动构建(使用普通的旧HTML和JS).我仍然希望利用Symfony的表单验证功能和CSRF保护.但是,出于某种原因,当使用isValid()手动创建表单时,我无法使CSRF正常工作.

这是我想要完成的一个例子:

在我的视图控制器中,我设置了_token:

$_token = $this->get('form.csrf_provider')->generateCsrfToken('form');
Run Code Online (Sandbox Code Playgroud)

在我看来(手动创建的表单)(从我的视图控制器获取_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>
Run Code Online (Sandbox Code Playgroud)

在我的动作控制器中(当表单提交时,我正在尝试执行以下操作):

//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...
Run Code Online (Sandbox Code Playgroud)

出于某种原因,我不能让isValid()工作,我怀疑我的_token是没有正确使用的东西,但我不明白为什么.有没有人真正使手动表单与Symfony组件一起工作?有没有人对如何使这项工作有任何建议?

基本上,我想要完成的是:

  1. 手动创建HTML表单(具有CSFR保护且没有 TWIG表单小部件功能)

  2. 使用Symfony的表单功能来验证该表单

谢谢.

Jov*_*vic 8

我认为你的意图不符合(传递给你的CSRF提供者的论点).我试着像你上面写的那样生成表单并且突破了令牌的生成.价值是unknown.

所以,尝试传递unknown而不是form你的generateCsrfToken电话,希望它应该工作.;)

编辑:

我刚刚完成了一些挖掘,现在确实很有意义.

看看课程FormTypeCsrfExtension.显然,它是用于CSRF令牌保护的默认扩展.在线#80(可能不是你的情况下这个)setDefaultOptions,通常在表单类型中重写方法.无论如何,有一个默认选项intention,其值为unknown==>我们在这里看到的.

我的猜测是,您可以通过传递intention和设置自己的值轻松覆盖您自己的表单类型中的此选项(就像您希望csrf_protection完全禁用CSRF保护时传递=> false一样).


Pre*_*ays 5

注意:意图不再默认为未知.当我在symfony 2.3中检查出来时,它会默认为类型名称:

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

如果有一些编程方式可以使用而不必依赖这些默认值,那将是一件好事.