使用symfony2表单类型的CSRF无效

时间:2013-10-23 13:10:41

标签: symfony csrf

我在一个动作中创建了2个表单,这些表单由jquery ajax提交给其他2个动作。现在,问题是 - 只有第一种形式有效。编辑表单抛出csrf令牌无效。为什么会这样?我的代码:

创建表单:

$project = new Project();
      $addProjectForm = $this->createForm(new AddProjectType(), $project, [
        'action' => $this->generateUrl('tfpt_portfolio_versionhistory_addproject'),
        'method' => 'POST',
        'attr' => ['id' => 'newProjectForm']
      ]);
      $editProjectForm = $this->createForm(new EditProjectType(), $project, [
        'action' => $this->generateUrl('tfpt_portfolio_versionhistory_editproject'),
        'method' => 'POST',
        'attr' => ['id' => 'editProjectForm']
      ]);

处理提交编辑表单(但添加表单完全相同):

$project = new Project();
      $form = $this->createForm(new EditProjectType(), $project);

      $form->handleRequest($request);
      if($form->isValid()){
        //handle form
      }
}

这两种形式之间唯一的差异是编辑表单还有一个字段 - 隐藏ID。两者都是由jquery提交的那样:

var form = $("#editProjectForm")
            if(form.valid()){
                $("#loader").show();
                $.ajax({
                    type: form.attr('method'),
                    url: form.attr('action'),
                    data: form.serialize()
                }).done(function(data){
                       //result
                            }
                        });

我会显示这样的表格:

 {{ form_start(editProjectForm) }}
 {{ form_errors(editProjectForm) }}
 {{ form_widget(editProjectForm.name) }}
 {{ form_widget(editProjectForm.id) }}
 {{ form_rest(editProjectForm) }}
 {{ form_end(editProjectForm) }}

有人可以指出我的错误吗?是不是可以在一个动作中嵌入3个表单?或者我必须以其他方式生成CSRF?

@Edit:我将symfony更新到最新版本,现在它的工作正常。似乎这个版本有一个错误或我有一些供应商代码缺乏。无论如何,问题已解决。

1 个答案:

答案 0 :(得分:2)

我认为你必须在控制器中创建两个令牌:

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

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

并在隐藏字段中放入视图。然后验证处理表单

的控制器操作
# Here you can validate the 'add' or 'edit' token
if (!$this->get('form.csrf_provider')->isCsrfTokenValid('add', $token)) {

    $respuesta = array('mensaje' => 'Oops! Invalid token.',
                       'token' => $token);
    return new Response(json_encode($respuesta));
}