【发布时间】:2012-12-15 07:54:22
【问题描述】:
编辑:最后有一个 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;博士: 使用带有 *entity*Type 调用的 createForm 调用可以正常工作,使用 createFormBuilder() 创建我自己的表单在每次提交时都会遇到 CSRF 错误......两者都使用相同的 _token。
【问题讨论】:
-
可能是一个奇怪的问题,但会话有效吗?令牌是从表单的 id 和会话的 id 生成的,如果您在每次浏览量中获得一个新的会话 id,它可能会像这样显示自己。
-
我还没有搞乱会话。我正在将现有站点转换为 symfony 并边走边学,但是当我使用 createForm 调用时发现它可以工作,这让我认为这不是问题。
-
您确认输出的 html 中没有隐藏的输入标签吗?