Search code examples
symfonysymfony-formssymfony-security

CSRF protection, error if turned on, error if turned off?


I am working on a web application and running into a problem when I submit my form it shows a CSRF protection error, This would'nt be a problem as I do not need it in this form(contains no sensitive data and I have implemented that only users with some privilige(role) can acces this page).

My problem is this when I use 'csrf_protection' => false, in my FormType options I get the following error: Some mandatory parameters are missing ("id") to generate a URL for route "myroute"

I wouldn't mind CSRF protection being on but then it shows this ugly error in my twig:

CSRF token invalid, try to send the form aigan

Yes i know the above block isnt exatcly what it says but I translated it from my native language.

Does anyone know a quick fix for this?

Controller Function

    /**
 * @Route("/{id}/edit", name="score_edit", methods={"GET","POST"})
 */
public function edit(Request $request, Duel $duel, DuelRepository $duelRepository): Response
{

    $form = $this->createForm(ScoreType::class, $duel);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $this->getDoctrine()->getManager()->flush();

        return $this->redirectToRoute('score_edit');
    }

    return $this->render('score/edit.html.twig', [
        'duels' => $duelRepository->findAll(),
        'duel' => $duel,
        'form' => $form->createView(),
    ]);
}

Form Type

    class ScoreType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('puntenP1', TextareaType::class, [
                'label' => 'Punten',
                'attr' => array('style' => 'height: 25px;')
            ])
            ->add('eerstenP1', TextareaType::class, [
                'label' => 'Eersten',
                'attr' => array('style' => 'height: 25px;')
            ])
            ->add('puntenP2', TextareaType::class, [
                'label' => 'Punten',
                'attr' => array('style' => 'height: 25px;')
            ])
            ->add('eerstenP2', TextareaType::class, [
                'label' => 'Eersten',
                'attr' => array('style' => 'height: 25px;')
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Duel::class,
            //csrf protection not needed for "scores"
            //'csrf_protection' => false,
        ]);
    }
}

Twig file

   {{ form_start(form) }}

<div class="row">
    <div class="col">
        <p><b>Partuur 1</b></p>
        {{ duel.team1 }}
    </div>
</div>

<div class="row">
    <div class="col">
        {{ form_row(form.puntenP1) }}
        <p>Huidig: {{ duel.puntenP1 }}</p>
    </div>
</div>

<div class="row">
    <div class="col">
        {{ form_row(form.eerstenP1) }}
       <p>Huidig: {{ duel.eerstenP1 }}</p>
    </div>
</div>
<hr>
<div class="row">
    <div class="col">
        <p><b>Partuur 2</b></p>
        {{ duel.team2 }}
    </div>
</div>

<div class="row">
    <div class="col">
        {{ form_row(form.puntenP2) }}
        <p>Huidig: {{ duel.puntenP2 }}</p>
    </div>
</div>

<div class="row">
    <div class="col">
        {{ form_row(form.eerstenP2) }}
        <p>Huidig: {{ duel.eerstenP2 }}</p>
    </div>
</div>
    {{ form_widget(form) }}

    <button class="btn btn-success" style="margin-top: 10px">{{ button_label|default('Save') }}</button>

{{ form_end(form) }}

Solution

  • This is the code that causes the problem:

    return $this->redirectToRoute('score_edit');
    

    You redirect the user to this route without parameters, but the route has required parameters:

    @Route("/{id}/edit", name="score_edit", methods={"GET","POST"})
    

    You have to add the required parameter to your route:

    return $this->redirectToRoute('score_edit', [
        'id' => $duel->getId(),
    ]);