本文介绍了在 Symfony2 中手动创建表单,但仍然在功能上使用它的 CSRF 和 isValid()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

OK, I googled this hard, but everything I find talks about Symfony forms in context of regular Symfony form processing (e.g. form_widget(), creating FormType class, etc.). I have many such forms in my Symfony project, they work great.

但是:

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

I also have some pretty complex AJAX forms that I would like to build manually (using plain old HTML and JS). I do still want to utilize Symfony's Form validation capabilities and CSRF protection. However, for some reason I can't get CSRF working when using isValid() for manually created forms.

这是我试图完成的一个例子:

This is an example of what I am trying to accomplish:

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

In my view controller I set _token:

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

在我看来(手动创建的表单)(从我的视图控制器中获取 _token):

In my view (manually created form) (getting _token from my view controller):

<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>

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

In my action controller (when form submitted, I am TRYING to do the following):

//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 组件手动制作过表单?有人对如何使这项工作有任何建议吗?

For some reason I can't get isValid() working, I suspect that my _token is thing not properly used, but I am out of ideas why. Have anyone actually made manually forms work with Symfony components? Does anyone have any suggestions on how to make this work?

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

Basically, what I want to accomplish is:

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

  1. Manually create HTML form (with CSFR protection and without TWIG form widget functions)

使用 Symfony 的表单功能来验证表单

Use Symfony's form functionality to validate that form

谢谢.

推荐答案

我认为您在这里与意图不匹配(传递给您的 CSRF 提供者的参数).我尝试按照你上面写的方式生成表单并断点了令牌的生成.值是unknown.

I think you're mismatching the intention here (argument passed to your CSRF provider). I tried generating form as you wrote above and break-pointed the generation of token. The value was unknown.

因此,尝试将 unknown 而不是 form 传递给您的 generateCsrfToken 调用,希望它可以工作.;)

So, try passing unknown instead of form to your generateCsrfToken call and hopefully it should work. ;)

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

I have just finished some digging and it now does make perfect sense.

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

Look at the class FormTypeCsrfExtension. Apparently, it's the default extension used for CSRF token protection. On the line #80 (might not be this one exactly in your case) there is method setDefaultOptions that is usually overridden in your form types. Anyhow, there is a default options called intention that has a value of unknown ==> the one we are seeing here.

我的猜测是,您可以通过传递 intention 并设置自己的值(就像传递 csrf_protection =>如果您想完全禁用 CSRF 保护,则为 false).

My guess is that you could easily override this option in your own form type just by passing intention and setting your own value (just as you would pass csrf_protection => false when you would want to disable CSRF protection altogether).

这篇关于在 Symfony2 中手动创建表单,但仍然在功能上使用它的 CSRF 和 isValid()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 14:32