Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 Form with CSRF passed through JQuery AJAX

I am developing a comments box that will save the comment through a JQuery AJAX call.

JQuery

Here's the JQuery code for that (this works seamlessly):

$(".post-comment").click(function() {
    var $form = $(this).closest("form");

    if($form)
    {
        $.ajax({
            type: "POST",
            url: Routing.generate('discussion_create'),
            data: $form.serialize(),
            cache: false,
            success: function(html){
                alert("Success!");
                // Output something                  
            }
        });
    }
    else
    {
        alert("An error occured");
    }
    return false;   
});

Symfony2 Controller

The Symfony2 controller method then picks up the form data and processes it. As part of that process it checks to see if the form is valid:

$entry = new Discussion();
$discussionForm = $this->createForm(new DiscussionType(), $entry);

if ($request->getMethod() == 'POST') {

    $discussionForm->bindRequest($request);

    if ($discussionForm->isValid()) {

This check is not returning true. In the else I extract what error messages have been given and get:

Array
(
    [0] => The CSRF token is invalid. Please try to resubmit the form
)

The CSRF token is being passed via post just as it would if the form was submitted synchronously.

Another possible issue.. Unique Form Id's

The form I am using is created by a form type class. On any given page there will be several comments forms. As symfony2 uses the getName() method of the type class to populate the forms ID attribute, I have modified it like so:

public function getName()
{
    return 'discussionForm' . $randomNumber;
}

This allows multiple comments forms without the same id e.g. discussionForm20, discussionForm21, discussionForm22 etc.

I could remove the symfony2 Form component from the mix and generate the form / process the submission using standard PHP logic but I'm resisting that for now.

Does anyone know why the forms CSRF token is invalid? Any suggestions on how this could be modified or how you do it?

like image 656
Rich Avatar asked Jan 25 '12 12:01

Rich


1 Answers

Try with the adequate JQuery function: submit() ^^ In my solution I suppose that your form has the id "comment_form". Works on all my sf2 projects:

$('#comment_form').submit(function(e) {

    var url = $(this).attr("action");

    $.ajax({
        type: "POST",
        url: url, // Or your url generator like Routing.generate('discussion_create')
        data: $(this).serialize(),
        dataType: "html",
        success: function(msg){

            alert("Success!");

        }
    });

    return false;

});

The CSRF Field would normally be sent !

And don't forget to add the twig tag {{ form_rest(form) }} in your form template, that will generate all hidden field like CSRF.

like image 169
Sybio Avatar answered Oct 05 '22 17:10

Sybio