0

编辑:最后有一个 Tl;Dr ...

在使用 symfony2 和自动生成的表单时,我不断收到 CSRF 错误。

这是我的控制器:(调用 new 以显示表单,调用 create 提交)

public function newAction($guru)
{

    //Make the Entity Manager
    $em = $this->getDoctrine()
            ->getEntityManager();
    $guru = $em->getRepository('TSNStatsBundle:Guru')
            ->findOneById($guru);
    //If the guru id exists        
    if ($guru)
    {
        $alert = new Alert();
        //Create default values
        $time = new \DateTime(2012-12-30);
        $time->setTime(23,59);

        //Set default times to "none available (23:59)"
        $alert->setText($time)
        ->setEmail($time)
        ->setTwitter($time)
        ->setChat($time)
        ->setGuru($guru);

        //Make the form, set types, 
        $formBuilder = $this->createFormBuilder($alert);


         $formBuilder->add('buy', 'checkbox', array(
                    'required' => false
                ))
                ->add('date', 'date', array(
                    'input' => 'datetime',
                    'widget' => 'single_text'
                ))
                ->add('stock', new StockType());
        if ($guru->getInstantAlerts() ==1)
        {
            if ($guru->getText() == 1)
            {
                $formBuilder->add('text', 'time', array(
                       'input' => 'datetime',
                       'widget' => 'text',

                   ));
            }
            if ($guru->getEmail() == 1)
            {
                $formBuilder->add('email', 'time', array(
                       'input' => 'datetime',
                       'widget' => 'text',

                   ));
            }
            if ($guru->getTwitter() == 1)
            {
                $formBuilder->add('twitter', 'time', array(
                       'input' => 'datetime',
                       'widget' => 'text',

                   ));
            }
            if ($guru->getChat() == 1)
            {
                $formBuilder->add('chat', 'time', array(
                       'input' => 'datetime',
                       'widget' => 'text',

                   ));
            }
        }
        $formBuilder->add('size')
                ->add('short', 'checkbox', array(
                    'required' => false
                ))
                ->add('his')
                ->add('guru');
         $form = $formBuilder->getForm();



        return $this->render('TSNStatsBundle:Buy:new.html.twig', array(
            'form' => $form->createView(),
            'guru' => $guru
        ));



    }
    else
    {
        //your guru ain't real bro!
    }
    return $this->render('TSNStatsBundle:Buy:new.html.twig', array(
        'alert' => $alert,
        'form' => $form->createView(),
        'guru' => $guru->getName()

     ));
}

public function createAction()
{
    $alert = new Alert();

    $form = $this->createForm(new AlertType(), $alert);
    $request = $this->getRequest();
    if ($this->getRequest()->getMethod() == 'POST') {
        $form ->bind($request);


        if ($form->isValid())
        {
            $em = $this->getDoctrine()
                    ->getEntityManager();
            $em->persist($alert);
            $em->flush();

            return $this->redirect($this->generateUrl('new_alert', array(
                'guru' => 2
            ) ));

        }
    }

    return $this->render('TSNStatsBundle:Buy:errors.html.twig', array(
          'errors' => $form->getErrors()
    ));

}

这是我的模板:

Adding entry for {{ guru }}
<form action="{{ path('create_alert' ) }}" method="post" {{ form_enctype(form) }} class="alert">
{{ form_widget(form) }}
<p>
    <input type="submit" value="Submit">
</p>
</form>

据我所知,一切都在书本上。每次我刷新时,每个表单都有一个 _token 值,它被调用的小部件,所以所有部分都应该在那里......

谢谢,

编辑:当我将整个表单创建过程替换为:

$form = $this->createForm(new AlertType(), $alert);

然后它再次工作。问题是我想要的逻辑不属于“类型”类。那以及我这样做的方式应该正确的事实?它与我在表单中添加元素的方式有什么关系吗?这是我认为我的构建与 createForm() 构建的唯一不同之处。

Tl; Dr:使用带有 *entity*Type 调用的 createForm 调用可以正常工作,使用 createFormBuilder() 创建我自己的表单在每次提交时都会遇到 CSRF 错误.... 两者都使用相同的 _token。

4

3 回答 3

2

也许使用它会帮助你:

{{form_widget(form._token)}}
于 2013-02-16T13:48:40.860 回答
1

尝试替换

{{ form_widget(form) }}
{{ form_rest(form) }}

为了

{{ form_widget(form) }}
于 2012-12-31T02:36:18.537 回答
0

您可以将与表单类型中相同的 $options 数组传递给 FormBuilder,并且可以通过以下方式关闭 csrf 保护:

$this->createFormBuilder($object, $options = array(
    'csrf_protection' => false,
));

原始示例: http ://symfony.com/doc/current/book/forms.html#csrf-protection

于 2015-02-27T16:10:38.283 回答