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.
The CSRF token is invalid. Please try to resubmit the form.
What works:
- the regular form submission, ie, without Ajax
- with Ajax I checked that $_POST is correctly populated, including the CSFR token, just before the submission on the controller side, as follows:
$form->submit($request->request->get($form->getName('user')));
As requested, see below output of
var_dump($request->request->get($form->getName('user')));
array(8) {
["name"]=> string(9) "fafdffafa"
["avatar"]=> string(9) "dfafffafa"
["cityId"]=> string(1) "6"
["phone"]=> string(14) "33434343434344"
["email"]=> array(2) {
["first"]=> string(22) "myemail@gmail.com"
["second"]=> string(22) "myemail@gmail.com" }
["plainPassword"]=> array(2) {
["first"]=> string(8) "senha444"
["second"]=> string(8) "senha444" }
["blogSubs"]=> string(1) "1"
["_token"]=> string(43) "hLhyoRxVYmJ_FWK0FqXmiiEYZMZ77fDAWvxCZMXCtxw" }
Just to confirm that if I just comment out the javascript below the submission will work and the entity will be persisted.
This is the same var_dump, this time for when things work.
array(9) {
["name"]=> string(12) "dfdfdfdfafaf"
["avatar"]=> string(13) "dfdfdfdafdafa"
["cityId"]=> string(1) "8"
["phone"]=> string(16) "3343434343343343"
["email"]=> array(2) {
["first"]=> string(22) "myemail@gmail.com"
["second"]=> string(22) "myemail@gmail.com" }
["plainPassword"]=> array(2) {
["first"]=> string(8) "senha444"
["second"]=> string(8) "senha444" }
["blogSubs"]=> string(1) "1"
["save"]=> string(0) ""
["_token"]=> string(43) "hLhyoRxVYmJ_FWK0FqXmiiEYZMZ77fDAWvxCZMXCtxw" }
This is the submit button generated by Symfony, but not captured by js serialization.
<button type="submit" id="user_save" name="user[save]" class="btn-default btn">Créer mon compte</button>
The form ( I am skipping the form $builder as it seems unnecessary )
app/Resources/views/common/register.html.twig
{{ form_start(form, { 'attr': { 'id': 'signup_form' }}) }}
<div class="contact input-group">
{{ form_widget(form.name) }}
</div>
<div class="contact input-group">
{{ form_widget(form.avatar) }}
<span class="input-group-addon" id="info_avatar">
<i class="fa fa-info"></i>
</span>
</div>
<div class="contact input-group">
{{ form_widget(form.cityId) }}
</div>
<div class="contact input-group">
{{ form_widget(form.phone) }}
</div>
<div class="contact input-group">
{{ form_widget(form.email) }}
</div>
<div class="contact input-group">
{{ form_widget(form.plainPassword) }}
</div>
<div class="contact">
{{ form_widget(form.blogSubs) }}
</div>
<div class="contact form-group ">
{{ form_widget(form.save) }}
</div>
{{ form_end(form) }}
The javascript on the same file:
<script>
$('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);
}
});
});
</script>
And the controller ( the getErrorMessages() method was found on SO.)
/src/UsedBundle/Controller/RegistrationController.php
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->createForm(UserType::class, $user);
if ($request->isMethod('POST')) {
var_dump($_POST);
$form->submit($request->request->get($form->getName('user')));
if(!$form->isValid()){
$errors = $this->getErrorMessages($form);
var_dump($errors);
}
if ($form->isSubmitted() && $form->isValid()) {
$password = $this->get('security.password_encoder')
->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
$email = $user->getEmail();
$user->setUserKey( $email );
$user->setUserKeyTime();
$user->setDateReg();
$em = $this->getDoctrine()->getManager('used');
$em->persist($user);
$em->flush();
return new JsonResponse(array('message' => 'Success!'));
}
}else{
return $this->render(
'common/register.html.twig',
array('form' => $form->createView())
);
}
}
protected function getErrorMessages($form)
{
$errors = array();
foreach ($form->getErrors() as $key => $error) {
$errors[] = $error->getMessage();
}
foreach ($form->all() as $child) {
if (!$child->isValid()) {
$errors[$child->getName()] = $this->getErrorMessages($child);
}
}
return $errors;
}
}