title: Symfony 3 - The CSRF token is invalid ONLY when submitting with AJAX
body: <p>After looking around I could not find a solution to this. I am getting error below ONLY when submitting thru Ajax. Meaning that I have beforehand submitted the form in the regular Symfony fashion without an issue. </p>
  
  <blockquote>
    <p>The CSRF token is invalid. Please try to resubmit the form.</p>
  </blockquote>
  
  <p>What works:</p>
  
  <ul>
  <li>the regular form submission, ie, without Ajax</li>
  <li>with Ajax I checked that $_POST is correctly populated, including the CSFR token, just before the submission on the controller side, as follows:</li>
  </ul>
  
  <blockquote>
    <p>$form->submit($request->request->get($form->getName('user')));</p>
  </blockquote>
  
  <p>As requested, see below output of </p>
  
  <blockquote>
    <p>var_dump($request->request->get($form->getName('user')));</p>
  </blockquote>
  
  <pre><code>array(8) { 
  ["name"]=&gt; string(9) "fafdffafa" 
  ["avatar"]=&gt; string(9) "dfafffafa" 
  ["cityId"]=&gt; string(1) "6" 
  ["phone"]=&gt; string(14) "33434343434344" 
  ["email"]=&gt; array(2) { 
        ["first"]=&gt; string(22) "myemail@gmail.com" 
        ["second"]=&gt; string(22) "myemail@gmail.com" } 
  ["plainPassword"]=&gt; array(2) { 
        ["first"]=&gt; string(8) "senha444" 
        ["second"]=&gt; string(8) "senha444" } 
  ["blogSubs"]=&gt; string(1) "1" 
  ["_token"]=&gt; string(43) "hLhyoRxVYmJ_FWK0FqXmiiEYZMZ77fDAWvxCZMXCtxw" }
  </code></pre>
  
  <p>Just to confirm that <strong>if I just comment out the javascript below</strong> the submission will work and the entity will be persisted. </p>
  
  <p>This is the same var_dump, this time for when things work.</p>
  
  <pre><code>array(9) { 
  ["name"]=&gt; string(12) "dfdfdfdfafaf" 
  ["avatar"]=&gt; string(13) "dfdfdfdafdafa" 
  ["cityId"]=&gt; string(1) "8" 
  ["phone"]=&gt; string(16) "3343434343343343" 
  ["email"]=&gt; array(2) { 
      ["first"]=&gt; string(22) "myemail@gmail.com" 
      ["second"]=&gt; string(22) "myemail@gmail.com" }
  ["plainPassword"]=&gt; array(2) { 
      ["first"]=&gt; string(8) "senha444" 
      ["second"]=&gt; string(8) "senha444" } 
  ["blogSubs"]=&gt; string(1) "1" 
  ["save"]=&gt; string(0) "" 
  ["_token"]=&gt; string(43) "hLhyoRxVYmJ_FWK0FqXmiiEYZMZ77fDAWvxCZMXCtxw" }
  </code></pre>
  
  <p>This is the submit button generated by Symfony, but not captured by js serialization. </p>
  
  <pre><code>&lt;button type="submit" id="user_save" name="user[save]" class="btn-default btn"&gt;Créer mon compte&lt;/button&gt;
  </code></pre>
  
  <p>The form ( I am skipping the form $builder as it seems unnecessary )</p>
  
  <p>app/Resources/views/common/register.html.twig</p>
  
  <pre><code>{{ form_start(form, { 'attr': { 'id': 'signup_form' }}) }}
      &lt;div class="contact input-group"&gt;
          {{ form_widget(form.name) }}
      &lt;/div&gt;
      &lt;div class="contact input-group"&gt;
          {{ form_widget(form.avatar) }}
          &lt;span class="input-group-addon" id="info_avatar"&gt;
              &lt;i class="fa fa-info"&gt;&lt;/i&gt;
          &lt;/span&gt;       
      &lt;/div&gt;
      &lt;div class="contact input-group"&gt;
          {{ form_widget(form.cityId) }}
      &lt;/div&gt;
      &lt;div class="contact input-group"&gt;
          {{ form_widget(form.phone) }}           
      &lt;/div&gt;
      &lt;div class="contact input-group"&gt;
          {{ form_widget(form.email) }}
      &lt;/div&gt;
      &lt;div class="contact input-group"&gt;
          {{ form_widget(form.plainPassword) }}
      &lt;/div&gt;
      &lt;div class="contact"&gt;
          {{ form_widget(form.blogSubs) }}
      &lt;/div&gt;
      &lt;div class="contact form-group "&gt;
          {{ form_widget(form.save) }}
      &lt;/div&gt;
  {{ form_end(form) }} 
  </code></pre>
  
  <p>The javascript on the same file:</p>
  
  <pre><code>&lt;script&gt;
      $('body').on('submit','#signup_form',function(event) {
          event.preventDefault();
          var str = $("#signup_form").serialize();
          $.ajax({
              url: "/inscription",
              type: "POST",
              dataType:"json",
              data: str,
              success: function (data) {
                              alert(data);
              }   
          });
      });
    &lt;/script&gt;
  </code></pre>
  
  <p>And the controller ( the getErrorMessages() method was found on SO.)</p>
  
  <p>/src/UsedBundle/Controller/RegistrationController.php</p>
  
  <pre><code>namespace UsedBundle\Controller;
  
  use UsedBundle\Form\UserType;
  use UsedBundle\Entity\User;
  use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  use Symfony\Component\HttpFoundation\Request;
  use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  use Doctrine\ORM\EntityManagerInterface;
  use Symfony\Component\HttpFoundation\JsonResponse;
  
  class RegistrationController extends Controller
  {
  /**
   * @Route("/inscription", name="inscription")
   */
  public function registerAction(Request $request)
  {
      $user = new User();
      $form = $this-&gt;createForm(UserType::class, $user);
  
      if ($request-&gt;isMethod('POST')) {
          var_dump($_POST);
          $form-&gt;submit($request-&gt;request-&gt;get($form-&gt;getName('user')));
          if(!$form-&gt;isValid()){ 
              $errors = $this-&gt;getErrorMessages($form);
              var_dump($errors);
          }
          if ($form-&gt;isSubmitted() &amp;&amp; $form-&gt;isValid()) {
              $password = $this-&gt;get('security.password_encoder')
                  -&gt;encodePassword($user, $user-&gt;getPlainPassword());
              $user-&gt;setPassword($password);
              $email = $user-&gt;getEmail();
              $user-&gt;setUserKey( $email );
              $user-&gt;setUserKeyTime();
              $user-&gt;setDateReg();
              $em = $this-&gt;getDoctrine()-&gt;getManager('used');
              $em-&gt;persist($user);
              $em-&gt;flush();
              return new JsonResponse(array('message' =&gt; 'Success!'));
          }
      }else{
          return $this-&gt;render(
              'common/register.html.twig',
              array('form' =&gt; $form-&gt;createView())
          );           
      }
  }
  
  protected function getErrorMessages($form) 
  {
      $errors = array();
      foreach ($form-&gt;getErrors() as $key =&gt; $error) {
          $errors[] = $error-&gt;getMessage();
      }
  
      foreach ($form-&gt;all() as $child) {
          if (!$child-&gt;isValid()) {
              $errors[$child-&gt;getName()] = $this-&gt;getErrorMessages($child);
          }
      }
  
      return $errors;
  } 
  }
  </code></pre>