简体   繁体   English

CSRF 令牌无效。 请尝试重新提交表单。 Symfony 4

[英]The CSRF token is invalid. Please try to resubmit the form. Symfony 4

In my form user must choose an option to then select users based on it.在我的表单中,用户必须选择一个选项,然后基于它的 select 用户。

I'm getting an error every time im trying to submit my form.每次我尝试提交表单时都会出错。
The CSRF token is invalid. CSRF 令牌无效。 Please try to resubmit the form.请尝试重新提交表单。

I tried to user {{ form_row(form._token) }}, but it doesnt work.我尝试使用 {{ form_row(form._token) }},但它不起作用。 Symfony tell me that the value of the csrf token is empty. Symfony 告诉我csrf token 的值为空。

My view:我的观点:

<div class="card">
  <div class="card-body">
     {{ form_start(form) }}
         {{ form_rest(form) }}
         <button class="btn btn-info">Envoyer</button>
      {{ form_end(form) }}
   </div>
</div>
    <script>
        $(document).on('change', '#bsv_send_cultures', function () {
            let $field = $(this)
            let $form = $field.closest('form')
            let data = {}
            data[$field.attr('name')] = $field.val()
            $.post($form.attr('action'), data).then(function (data) {
                let $input = $(data).find('#bsv_send_user')
                $('#bsv_send_user').replaceWith( $input )
                $('#bsv_send_user').append( "<input id=\"selectAll\" type=\"checkbox\"><label for='selectAll'>Sélectioner tous</label>" )
                $("#selectAll").click(function(){
                    $("input[type=checkbox]").prop('checked', $(this).prop('checked'));

                });
            })
        })
    </script>

My form builder我的表单生成器

class BsvSendType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('cultures', EntityType::class, [
                'class' => IndexCultures::class,
                'choice_label' => 'name',
                'mapped' => false,
                'required' => false,
                'placeholder' => 'Sélectionnez une culture',
                'attr' => [
                    'class' => 'select2'
                ]
            ])
            ->add('display_at', DateType::class, [
                'widget' => 'single_text',
                'html5' => false,
                'mapped' => false,
                'required' => false,
                'attr' => [
                    'class' => 'js-datepicker',
                    'autocomplete' => 'off'
                ],
                'label' => 'Date d\'envoi',
                'help' => 'Remplir uniquement en cas d\'envoi différé.'
            ])
        ;

        $builder->get( 'cultures')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) {
                $form = $event->getForm();
                $this->addUserField( $form->getParent(), $form->getData());
            }
        );

        $builder->addEventListener(
            FormEvents::POST_SET_DATA,
            function (FormEvent $event) {
                $form = $event->getForm();
                $this->addUserField( $form, null );
            }
        );
    }

    /**
     * @param FormInterface $form
     * @param IndexCultures|null $indexCultures
     */
    private function addUserField(FormInterface $form, ?IndexCultures $indexCultures)
    {
        if (is_null($indexCultures)) {
            $form->add('user', EntityType::class, [
                'class' => Users::class,
                'mapped' => false,
                'choices' => [],
                'required' => false,
                'placeholder' => 'Selectionner une culture avant de choisir un utilisateur'
            ]);
        } else {
            $form->add('user', EntityType::class, [
                'class' => Users::class,
                'choice_label' => function(Users $user) {
                    return $user->getIdentity();
                },
                'query_builder' => function (UsersRepository $er) use ( $indexCultures ) {
                    return $er->createQueryBuilder('u')
                        ->leftJoin( Exploitation::class, 'e', 'WITH', 'u.id = e.users')
                        ->leftJoin(Ilots::class, 'i', 'WITH', 'e.id = i.exploitation')
                        ->leftJoin(Cultures::class, 'c', 'WITH', 'i.id = c.ilot')
                        ->leftJoin(IndexCultures::class, 'ic', 'WITH','c.name = ic.id')
                        ->andWhere('ic.id = :indexC')
                        ->setParameter('indexC', $indexCultures->getId());
                },
                'mapped' => false,
                'expanded' => true,
                'multiple' => true
            ]);
        }
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => BsvUsers::class,
            'translation_domain' => 'forms'
        ]);
    }

My Controller我的 Controller

/**
     * @Route("/admin/bsv/send/{id}", name="admin.bsv.send", methods="GET|POST")
     * @param Bsv $bsv
     * @param Request $request
     * @return Response
     * @throws \Exception
     */
    public function send(Bsv $bsv, Request $request): Response
    {
        $bsvUsers = new BsvUsers();
        $form = $this->createForm(BsvSendType::class, $bsvUsers);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $data = $form->all();
            $customers = $data['user']->getData();
            $displayAt = $data['display_at']->getData();
            //-- Init
            $datetime = New \DateTime();
            //-- Update BSV info
            $bsv->setSendDate( $datetime );
            //-- Create relation
            foreach ($customers as $customer) {
                $relation = new BsvUsers();
                $this->em->persist($relation);
                $relation->setBsv($bsv);
                $relation->setCustomers($customer);
                $relation->setChecked(0);
                if ( $displayAt !== null ) {
                    $displayAt->setTime(8,00);
                    $relation->setDisplayAt($displayAt);
                } else {
                    $relation->setDisplayAt($datetime);
                }
            }
            $this->em->flush();
            $this->addFlash('success', 'BSV envoyé avec succès');
            return $this->redirectToRoute('admin.bsv.index');
        }

        return $this->render('admin/bsv/send.html.twig', [
            'bsv' => $bsv,
            'form' => $form->createView()
        ]);
    }

It looks like you are sending your form without the _token field, look at your JS:看起来您发送的表单没有_token字段,请查看您的 JS:

...

let data = {}
data[$field.attr('name')] = $field.val()
$.post($form.attr('action'), data).then(...)

...

Your data object contains only #bsv_send_cultures input value before being sent to the server, just add the #bsv_send__token input value to this object before sending it from your script.您的data object 在发送到服务器之前仅包含#bsv_send_cultures输入值,只需在从脚本发送之前将#bsv_send__token输入值添加到此 object 即可。

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

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