Маркер CSRF недействителен. Пожалуйста, попробуйте повторно отправить форму. Symfony 4 - PullRequest
0 голосов
/ 14 апреля 2020

В моей форме пользователь должен выбрать опцию, чтобы затем выбирать пользователей на ее основе.

Я получаю сообщение об ошибке каждый раз, когда я пытаюсь отправить свою форму.
Маркер CSRF недействительным. Пожалуйста, попробуйте повторно отправить форму.

Я пытался использовать пользователя {{form_row (form._token)}}, но это не работает. Symfony скажите, что значение токена csrf пусто.

Мой взгляд:

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

Мой конструктор форм

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'
        ]);
    }

Мой контроллер

/**
     * @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()
        ]);
    }

1 Ответ

1 голос
/ 15 апреля 2020

Похоже, что вы отправляете форму без поля _token, посмотрите на JS:

...

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

...

Ваш data объект содержит только #bsv_send_cultures входное значение перед отправкой на сервер, просто добавьте входное значение #bsv_send__token к этому объекту перед отправкой его из вашего скрипта.

...