Symfony : causes possibles pour un CSRF invalide

Le problème exposé dans ce sujet a été résolu.

Bonsoir,

J’ai un phénomène inédit sur Symfony : un formulaire d’édition me renvoie à la soumission :

"Le jeton CSRF est invalide. Veuillez renvoyer le formulaire."

Techniquement, j’utilise turbo-frame dans cette page pour faire très exactement la même chose que sur cette très bonne vidéo de Grafikart, aux environs de 4mn.

Ceci étant dit, quand j’essaye d’envoyer le même formulaire depuis sa page "normale", hors Turbo-Frame, ça me renvoie la même erreur.

A noter sur cette page, il y a un autre formulaire, de création celui-ci provenant d’une autre action de mon Controller, rendu dans un {% render %} de Twig.

Je vous mets le formulaire au cas où je sois trop fatigué pour voir une ânerie.

Qu’est-ce qui peut bien être à l’origine de cette erreur ?

Merci pour vos avis.

{% block body %}
<div class="container mt-5">
<turbo-frame id="book_{{ book.id }}">
    {{ form_start(bookEditionForm, {action: path('author.editBook', {id: book.id})}) }}
    <div class="row">
        <div class="col-12">  
            <div class="input-group input-group mb-3">
                <span class="input-group-text">{{ form_label(bookEditionForm.title) }}</span>
                {{ form_widget(bookEditionForm.title) }}  
            </div>          
        </div>
    </div>
    <div class="row">
        <div class="col-12">       
            <div class="input-group input-group mb-3">
                <span class="input-group-text">{{ form_label(bookEditionForm.editor) }}</span>     
                {{ form_widget(bookEditionForm.editor) }}
            </div>  
        </div>
    </div>
    <div class="row">
        <div class="col-6">       
            <div class="input-group input-group mb-3">
                <span class="input-group-text">{{ form_label(bookEditionForm.collection) }}</span>     
                {{ form_widget(bookEditionForm.collection) }}
            </div>  
        </div>        
        <div class="col-6"> 
            <div class="input-group input-group mb-3">
                <span class="input-group-text">{{ form_label(bookEditionForm.provider) }}</span>     
                {{ form_widget(bookEditionForm.provider) }}
            </div>           
        </div>
    </div>
    <div class="row">
        <div class="col-8">  
            <div class="input-group input-group mb-3">
                <span class="input-group-text">{{ form_label(bookEditionForm.codeEAN) }}</span>     
                {{ form_widget(bookEditionForm.codeEAN) }}
            </div>           
        </div>
        <div class="col-4"> 
            <div class="input-group input-group mb-3">
                <span class="input-group-text">{{ form_label(bookEditionForm.price) }}</span>     
                {{ form_widget(bookEditionForm.price) }}
            </div>  
        </div>
    </div>    
    {{ form_rest(bookEditionForm) }}
    {{ form_end(bookEditionForm) }}        
</turbo-frame>
</div>
{% endblock %}

Dans la console du serveur j’ai plus précisément :

CSRF validation failed: double-submit info was used in a previous request but is now missing.

Edit : mon souci pourrait venir du csrf_protection_controller.js fourni par Turbo bidule. Bizarre. Sur la même page j’ai un formulaire de création de l’entité Book, puis un tableau avec en bout de ligne editer/supprimer. Supprimer contient un "micro-formulaire" pour l’action, et éditer est un lien vers une autre page, qui amène donc le turbo-frame.

J’ai désactivé momentanément la protection CSRF sur ce formulaire d’édition en attendant de trouver l’origine de l’erreur. Si quelqu’un a une idée de choses que je peux faire pour débugger…

Edit 2 : la phrase CSFR validation vient de :

C:\wamp64\www\salondulivre\vendor\symfony\security-csrf\SameOriginCsrfTokenManager.php:
  164  
  165              if (!$isValidDoubleSubmit && (2 & ($previousCsrfProtection >> $shift))) {
  166:                 $this->logger?->warning('CSRF validation failed: double-submit info was used in a previous request but is now missing.');
  167  
  168                  return false;

Je ne sais pas ce que c’est que cette histoire de double-submit.

EDIT 3 :

La suppression de la sécurité me chagrinait. Du coup, je l’ai remise et testé la configuration par défaut proposée par la doc de Symfony :

framework:
    # ...
    csrf_protection: ~

Au lieu de la configuration écrite AUTOMATIQUEMENT (je n’y suis pour rien du tout) lors de l’installation de Symfony pour ce projet :

 framework:
     form:
         csrf_protection:
             token_id: submit

     csrf_protection:
         stateless_token_ids:
             - submit
             - authenticate
             - logout

Et là ça remarche. Vraiment étrange. Je ne crois pas avoir fait quoi que ce soit d’original sur cette application très basique utilisant la configuration de Symfony par défaut.

+0 -0

J’ai mis en résolu mais le problème est contourné, pas réellement résolu ^^

Dans le Controller envoyant ce formulaire, je le pré-remplis avec le champ Auteur, mais c’est tout. J’ai pu voir que cette technique est désormais considérée comme dépréciée, mais ce n’est pas bloquant. Tu penses que ça pourrait être l’origine de l’erreur initiale ?

Je ne pense pas qu’on puisse parler d’un bug, par contre il n’est pas impossible que tu aies un cas d’utilisation dont tu ne rends pas compte.
Je ne connais pas Symfony UX turbo, mais typiquement, il y a un passage de la documentation qui m’interpelle.

We also recommend that you place your script tags inside your head tag so that they aren’t reloaded on every navigation (Turbo re-executes any script tags inside body on every navigation). Add a defer attribute to each script tag to prevent it from blocking the page load. See Moving <script> inside <head> and the "defer" Attribute for more info.

Symfony UX Turbo Documentation (2.x) — Usage: 1. Make sure your JavaScript is Turbo ready, en date de message
+0 -0

Au temps pour moi, j’aurais dû dire "cas" plutôt qu’erreur : je suis probablement la cause de ce cas ^^. Mes scripts sont déjà dans le head, c’est la configuration par défaut du template base.html.twig.

Maintenant, j’avoue que je n’ai pas été spécialement convaincu par ma rapide découverte de UX-Turbo. Ca fait encore un langage avec ses nuances à apprendre, et j’avoue saturer un peu, d’autant que tout ce pan aurait été un bonus à mon application de salon du livre ; ce n’est pas rigoureusement indispensable.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte