web-dev-qa-db-fra.com

Le jeton CSRF n'est pas valide. S'il vous plaît essayer de soumettre à nouveau le formulaire

Je reçois ce message d'erreur chaque fois que j'essaie de soumettre le formulaire:

Le jeton CSRF n'est pas valide. S'il vous plaît essayer de soumettre à nouveau le formulaire

Mon code de formulaire est le suivant:

<form novalidate action="{{path('signup_index')}}" method="post" {{form_enctype(form)}} role="form" class="form-horizontal">
    <div class="form-group">
        {{ form_label(form.email, 'Email', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
        {{ form_widget(form.email, {'attr': {'class': 'col-md-2'}}) }}
        {{ form_errors(form.email) }}
    </div>

    <div class="form-group">
        {{ form_label(form.nickname, 'Nickname', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
        {{ form_widget(form.nickname, {'attr':{'class': 'col-md-2'}}) }}
        {{ form_errors(form.nickname, {'attr': {'class': 'col-md-3'}}) }}
    </div>
    <div class="form-group">
        {{ form_label(form.password, 'password', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
        {{ form_widget(form.password, {'attr': {'class': 'col-md-2'}}) }}
        {{ form_errors(form.password, {'attr': {'class': 'col-md-3'}}) }}
    </div>

    <div class="form-group">
        {{ form_label(form.password_repeat, 'Repeat password', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
        {{ form_widget(form.password_repeat, {'attr':{'class': 'col-md-2'}}) }}
        {{ form_errors(form.password_repeat, {'attr': {'class': 'col-md-3'}}) }}
    </div>
    <div class="form-group">
        <div class="col-md-1 control-label">
        <input type="submit" value="submit">
    </div>

    </div>
</form>

Des idées?

29

Vous devez ajouter le _token dans votre formulaire i.e

{{ form_row(form._token) }}

Pour l'instant, votre formulaire ne contient pas le champ de jeton CSRF. Si vous utilisez les fonctions de formulaire twig pour rendre votre formulaire comme form(form), le champ de jeton CSRF sera automatiquement rendu pour vous, mais votre code indique que vous rendez le formulaire avec du code HTML brut tel que <form></form>.

Ou bien, ajoutez simplement {{ form_rest(form) }} avant la balise de fermeture du formulaire.

Selon docs

Cela rend tous les champs qui n'ont pas encore été rendus pour le .__ donné. forme. C'est une bonne idée de toujours avoir cela quelque part dans votre formulaire car il va rendre les champs cachés pour vous et rendre tous les champs que vous avez oubliés rendre plus évident (car il rendra le champ pour vous).

form_rest (vue, variables)

79
M Khalid Junaid

Vous pouvez également voir ce message d'erreur si votre formulaire comporte de nombreux éléments.

Cette option dans php.ini cause du problème

; How many GET/POST/COOKIE input variables may be accepted
 max_input_vars = 1000

Le problème est que _token manque la demande PUT (GET).

En outre, il s'agit d'un gros fichiers. Augmenter le

upload_max_filesize

l'option résoudra le problème

22
zalex

Cela est dû au fait que les formulaires contiennent par défaut une protection CSRF, qui n'est pas nécessaire dans certains cas.

Vous pouvez désactiver cette protection CSRF dans votre classe de formulaire avec la méthode getDefaultOptions comme ceci:

// Other methods omitted

public function getDefaultOptions(array $options)
{
    return array(
        'csrf_protection' => false,
        // Rest of options omitted
    );
}

Si vous ne souhaitez pas désactiver la protection CSRF, vous devez alors rendre le champ de protection CSRF dans votre formulaire. Cela peut être fait en utilisant {{ form_rest(form) }} dans votre fichier de vue, comme ceci:

<form novalidate action="{{path('signup_index')}}" method="post" {{form_enctype(form)}} role="form" class="form-horizontal">
    <!-- Code omitted -->

    <div class="form-group">
        <div class="col-md-1 control-label">
            <input type="submit" value="submit">
        </div>

    </div>
    {{ form_rest(form) }}
</form>

{{ form_rest(form) }} affiche tous les champs que vous n'avez pas saisis manuellement.

9
user3577953

Avant votre tag </form> mis:

{{ form_rest(form) }}

Il insérera automatiquement d'autres entrées importantes (cachées).

5
Bc. Poklop

J'ai eu ce problème avec un comportement étrange: effacer le cache du navigateur ne l'a pas résolu, mais effacer les cookies (c'est-à-dire le cookie d'ID de session PHP) a résolu le problème.

Ceci doit être fait après que vous avez coché toutes les autres réponses, y compris en vérifiant que do avez le jeton dans un champ de saisie de formulaire masqué.

2
Benoit Duffez

J'ai eu cette erreur récemment. Il s'avère que mes paramètres de cookies étaient incorrects dans config.yml. L'ajout des paramètres cookie_path et cookie_domain à framework.session a résolu le problème.

2
Michael

En plus des suggestions d'autres personnes, vous pouvez obtenir des erreurs de jeton CSRF si le stockage de votre session ne fonctionne pas.

Dans un cas récent, un de mes collègues a changé le "préfixe_session" en une valeur contenant un espace.

session_prefix: 'My Website'

Ce stockage de session cassé, ce qui signifie que mon formulaire ne pouvait pas obtenir le jeton CSRF de la session.

2
Henry

J'ai fait face à un problème similaire. Après m'être assuré que le champ de jeton avait bien été rendu (voir la réponse acceptée), j'ai vérifié mes cookies . Il y avait 2 (!) Cookies pour le domaine dans mon navigateur Chrome, apparemment parce que j'exécutais l'application sur le même domaine qu'une autre application. , mais avec un autre port (par exemple, mydomain.com a défini le cookie d'origine pendant que l'application buggy était en cours d'exécution sur mydomain.com:123)Maintenant, apparemment, Chrome a envoyé le mauvais cookie, de sorte que la protection CSRF n'a pas pu lier le jeton au session correcte.

Solution: supprimez tous les cookies du domaine en question, assurez-vous de ne pas exécuter plusieurs applications sur le même domaine avec des ports différents.

0
lkoell

Dans mon cas, l'annotation maxSize de l'entité m'a posé problème, je l'ai donc augmentée de 2048 à 20048.

 /**
 * @Assert\File(
 *     maxSize = "20048k",
 *     mimeTypes = {"application/pdf", "application/x-pdf"},
 *     mimeTypesMessage = "Please upload a valid PDF"
 * )
 */
private $file;

espérons que cette réponse aide!

0
Jorgeeadan

Si vous avez converti votre formulaire de HTML ordinaire en twig, assurez-vous de ne pas avoir oublié la suppression d'une balise </form> de clôture. Silly erreur, mais comme j'ai découvert que c'est une cause possible pour ce problème.

Quand j'ai eu cette erreur, je ne pouvais pas le comprendre au début. J'utilise form_start() et form_end() pour générer le formulaire. Par conséquent, je n'aurais pas besoin d'ajouter explicitement le jeton avec form_row(form._token) ou d'utiliser form_rest() pour l'obtenir. Il devrait déjà avoir été ajouté automatiquement par form_end().

Le problème était que la vue sur laquelle je travaillais était celle que j'avais convertie de HTML simple à twig et que j'avais raté la suppression de la balise </form> de fermeture, donc au lieu de:

{{ form_end(form) }}

J'ai eu:

</form>
{{ form_end(form) }}

En fait, cela peut sembler être une erreur, mais ce n’est apparemment pas le cas. Ainsi, lorsque form_end() génère form_rest(), le formulaire est déjà fermé. Le code source généré par le formulaire était comme suit:

<form>
    <!-- all my form fields... -->
</form>
<input type="hidden" id="item__token" name="item[_token]" value="SQAOs1xIAL8REI0evGMjOsatLbo6uDzqBjVFfyD0PE4" />
</form>

Évidemment, la solution consiste à supprimer l’étiquette de fermeture supplémentaire et éventuellement à boire encore du café.

0
Don't Panic

J'ai eu la même erreur, mais dans mon cas, le problème était que mon application utilisait plusieurs domaines de premier niveau, alors que le cookie en utilisait un. La suppression de cookie_domain: ".%domain%" de framework.session dans config.yml a provoqué le paramétrage par défaut des cookies sur le domaine dans lequel se trouvait le formulaire, ce qui a résolu le problème.

0
ACJ

Si vous ne souhaitez pas utiliser form_row ou form_rest et souhaitez simplement accéder à la valeur de _token dans votre modèle de brindille. Utilisez le suivant:

<input type="hidden" name="form[_token]" value="{{ form._token.vars.value }}" />
0
Imran Zahoor