0
votes

We have a Symfony 4.3 app which has a page which makes multiple AJAX requests. Each AJAX response contains a few forms and each form has its own CSRF token. However, only one of the AJAX calls manages to store it's token in the session. Therefore all forms in the AJAX requests will fail with the message

The CSRF token is invalid. Please try to resubmit the form.

Except for one form which manages to have its token saved correctly in the session.

The session is stored in redis.

How can I make sure all CSRF tokens are stored in the session when making multiple AJAX calls?

1

1 Answers

0
votes

The CSRF token uses, in part, cookies. When you generate two CSRFs on one page and submit one of the forms, you're invalidating the cookie.

Without some extensions on the framework itself, I can only really see one way around this -- and it's rather roundabout:

What you could do is set up a controller that generates your app form.

At the initial page load, your controller will load the login form as well as the app form. Upon submitting the login form via AJAX, you'll also request ONLY the controller for the app form (which will also give the user a new cookie). With javascript, you could then extract the NEW csrf token from the new form and inject it into the original app form. Then, when you submit the app form, it should have a new, valid csrf token.

To illustrate:

Get app form and login form -> submit login via AJAX -> get app form via AJAX in background -> steal new app form's csrf token and inject it into first app form -> submit app form.

      $.ajaxSetup({
  headers: {
    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
  }
});

add this to your header->>

<meta name="csrf-token" content="{{ csrf_token() }}">