Créer des formes manuellement dans Symfony2, mais utiliser tout de même son CSRF et isValid() de manière fonctionnelle

OK, j'ai cherché sur Google, mais tout ce que je trouve parle des formes Symfony dans le contexte du traitement régulier des formes Symfony (par exemple form_widget(), la création de la classe FormType, etc.). J'ai beaucoup de telles formes dans mon projet Symfony, elles fonctionnent très bien.

mais:

j'ai aussi quelques formes AJAX assez complexes que je voudrais construire manuellement (en utilisant de vieux HTML et JS). Je veux toujours utiliser la validation de forme de Symfony capacités et protection CSRF. Cependant, pour une raison quelconque, Je ne peux pas faire fonctionner CSRF en utilisant isValid() pour manuellement formes créées.

Ceci est un exemple de ce que j'essaie d'accomplir:

dans mon contrôleur de vue j'ai mis _token:

$_token = $this->get('form.csrf_provider')->generateCsrfToken('form');

de mon point De vue ( manuellement créé forme) (_token de mon point de vue contrôleur):

<html>
  <form method="post">
    <input type="hidden" name="form[_token]" value="{{ _token }}">
    <input type="hidden" name="form[id]" value="1">
    <input type="submit" value="Submit">
  </form>
</html>

dans mon contrôleur d'action (lorsque le formulaire est soumis, j'essaie de faire ce qui suit):

//Create form (for validation purposes)
$form = $this->get('form.factory')
  ->createBuilder('form', array('id' => $request->get('id')))
  ->add('id', 'hidden')
  ->getForm();

//Bind form
$form->bind($request)

//Validate form
if($form->isValid()) {
  //... save data
}

//Return response...

pour une raison quelconque, je ne peux pas faire fonctionner isValid (), je soupçonne que mon _token n'est pas correctement utilisé, mais je ne sais pas pourquoi. Quelqu'un a-t-il fait fonctionner manuellement des formulaires avec des composants Symfony? Quelqu'un a-t-il des suggestions à faire pour que cela fonctionne?

fondamentalement, ce que je veux accomplir est:

  1. Créer manuellement le formulaire HTML (avec la protection CSFR et sans les fonctions de widget de forme de brindille)

  2. utilisez la fonctionnalité de formulaire de Symfony pour valider ce formulaire

Merci.

17
demandé sur user1863635 2013-04-27 00:53:25

4 réponses

je pense que vous êtes à la désadaptation de la intention ici (argument transmis à votre CSRF fournisseur). J'ai essayé de générer la forme comme vous l'avez écrit ci-dessus et de casser la génération de token. La valeur était unknown .

alors, essayez de passer unknown au lieu de form à votre appel generateCsrfToken et j'espère que ça devrait marcher. ;)

EDIT:

je viens de finir de creuser et il est maintenant ne fait logique.

regardez la classe FormTypeCsrfExtension . Apparemment, c'est l'extension par défaut utilisée pour la protection des tokens CSRF. Sur la ligne #80 (pourrait ne pas être celui-ci exactement dans votre cas) il y a la méthode setDefaultOptions qui est habituellement dépassée dans vos types de forme. Quoi qu'il en soit, il y a une option par défaut appelée intention qui a une valeur de unknown ==> celle que nous voyons ici.

je pense que vous pourriez facilement outrepasser cette option dans votre propre type de formulaire juste en passant intention et en définissant votre propre valeur (tout comme vous passeriez csrf_protection => false quand vous voudriez désactiver la protection CSRF tout à fait).

8
répondu Jovan Perovic 2013-04-30 15:42:10

Note: l'intention n'est plus inconnue par défaut. Quand j'ai vérifié cela dans symfony 2.3, il semblerait qu'il soit par défaut au nom de type:

$options['intention'] ?: ($builder->getName() ?: get_class($builder->getType()->getInnerType()))

ce serait bien s'il y avait un moyen programmatique pour faire sortir l'intention qui est utilisée au lieu d'avoir à compter sur ces défauts.

5
répondu PressingOnAlways 2014-06-17 19:36:17

j'ai vu que ceci est résolu mais j'ai aussi quelques problèmes de forme et j'ai vu un autre post ici:

symfony2 CSRF invalide

et leur solution me semble mieux que de faire mon propre jeton:

il n'y a aucun problème à utiliser {form_widget(form)} pour construire votre formulaire personnalisé. Tout ce que vous avez à faire est d'ajouter le _token comme ceci: {{ form_widget(form._token) }}

4
répondu G. Trennert 2017-05-23 12:09:39

ma solution en utilisant Symfony 2.8:

dans le Contrôleur d'action (lorsque le formulaire est soumis):

    $theToken = $request->get('Token');

    //Token Verification   
    $isValidToken = $this->isCsrfTokenValid('your_intention', $theToken);
    if ($isValidToken === false)
    {
        // Error
    }

vérifier cette page où j'ai trouvé l'info: http://api.symfony.com/2.8/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.html#method_isCsrfTokenValid

0
répondu baldychristophe 2016-08-12 13:13:58