简体   繁体   English

提交嵌入式表单时处理csrf令牌

[英]handle csrf token when submitting embedded forms

Using Symfony2.3.4 使用Symfony2.3.​​4

In my project I have the following classes: Services, Transport, Meals and Lodging. 在我的项目中,我有以下课程:服务,交通,膳食和住宿。
I embedded the three latter inside Services. 我将后三个嵌入到服务中。

I'm working on Services' new.html.twig view with the embedded forms in it and I got it to show all three entities' forms OK. 我正在使用Services的new.html.twig视图,其中包含嵌入式表单,并且可以显示所有三个实体的表单。 There's just one detail I'm not comfortable with: 只有一个我不满意的细节:

Here's the code as it is now: 这是现在的代码:

////ServicesController.php
public function newAction(Request $request, $id_person, $id_edition) {
        $entity = new Services();

        $meals = new Meals();
        $lodging = new Lodging();
        $transport = new Transport();
        $transport2 = new Transport();
        $entity->addLodging($lodging);
        $entity->addTransport($transport);
        $entity->addTransport($transport2);
        $entity->addMeals($meals);

        $form = $this->createCreateForm($entity);
        $form->bind($request);

PAUSE: the last line of code is the one I need some advice about: at first I put it because of what I read here but if I do it that way I get the The CSRF token is invalid. 暂停:最后一行代码是我需要一些建议的:刚开始时,由于我在这里所读的内容,我把它放了进去,但是如果这样做,我会得到CSRF令牌无效。 Please try to resubmit the form. 请尝试重新提交表格。 error and I took it out and it fixed, which is the right way?, should I had done something else instead?, any insights about it... 错误,我将其取出并修复,这是正确的方法?我应该做其他事情吗?对此有任何见解...

//continues...
        return $this->render('ServicesBundle:Services:new.html.twig', array(
                    'form' => $form->createView(),
                    'id_person' => $id_person,
                    'id_edition' => $id_edition));
    }

and the view: 和视图:

{# Services' new.html.twig #}
{% extends 'AdminBundle:Default:admin.html.twig' %}

{% block content -%}

<div class="row-fluid">
    <h2 class="new-tag">Services</h2>
    <form class="form-horizontal sf_admin_form_area" 
          action="{{ path('services_create',{'id_peson':person.id}) }}" 
          method="post" {{ form_enctype(form) }}>
          {{form_errors(form)}}

PAUSE:the last line wasn't there at first, I put it to see what was triggering the next IF 暂停:起初没有最后一行,我看一下是什么触发了下一个中频

{% if form_errors(form) != '' %}
   <div class="alert alert-error">
       <i class="glyphicon-ban-circle"></i>
       <h3>General "There's an error somewhere..." error message</h3>
   </div>
{% endif %}
<h3>Lodging</h3>
{%for lo in form.lodging%}
   {{ form_widget(lo) }}
{%endfor%}

<h3>Meals</h3>        
{%for me in form.meals%}
    {{ form_widget(me) }}
{%endfor%}

{%if person.type != 'ee'%}
   <h3>Transport</h3>
   {%for tr in form.transport%}
       {{ form_widget(tr) }}
   {%endfor%}        
{%endif%}

{{form_row(form._token)}}{#not sure about this guy, 
got the error with it and without it#}

<div class="form-actions">
    <button class="btn btn-primary">
        <i class="glyphicon-ok"></i> {{'Save' | trans}}</button>
    <a class="btn" href="{{ path('student',{'edition_id':id_edition}) }}">
        <i class="glyphicon-ban-circle"></i> {{'Cancel' | trans }}</a>
</div>
</form>
</div>
{% endblock %}

and finally the type's builder in case you need it 最后是类型的生成器,以备不时之需

public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('lodging', 'collection', array(
            'type' => new LodgingType()));
        $builder->add('transport', 'collection', array(
            'type' => new TransportType()));
        $builder->add('meals', 'collection', array(
            'type' => new MealsType(),
            'allow_add' => true));
    }

Since you only get the message when adding $form->bind($request) I recommend you try the following: 由于您仅在添加$form->bind($request)时收到消息,因此建议您尝试以下操作:

if ('POST' === $request->getMethod()) {
    $form->bind($request);
    if ($form->isValid()) {
        // Do something
    }
}

You only have to bind the request to the form on submit, as only then it contains data. 您仅需在提交时将请求绑定到表单,因为它仅包含数据。 This way you can keep the CSRF-token. 这样,您可以保留CSRF令牌。 Of course you also have to keep {{ form_widget(form._token) }} in your view. 当然,您还必须在视图中保留{{ form_widget(form._token) }}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM