0

I have a laravel page that allows users to save a search but only if they are logged in. They can log in with no problem or save a search with no problem, the CSRF token is accepted. However, if the user has to log in and then save a search I get the "CSRF token mismatch." error.

I'm assuming that a new token is generated on each post or database update but not sure. Should I be retrieving a new CSRF token after the post to the controller and then updating the CSRF inputs on the page?

I've tried with this in my header

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

and also using this in my forms

@csrf

and then in my ajax calls

var token    = $('[name=_token]').val();

The token is being passed in the parameters so I know it is there but will only work on the first ajax call

xjx424
  • 173
  • 2
  • 12

3 Answers3

1

I'm not sure how you're getting the data from ajax, but the token variable you have assigned may not be getting the right data. At least not if your meta above is what is setting it.

You might try changing your token setting using the content attrib, not val() as follows (IE test removing from the form and use the token you set in the meta):

var token = $('meta[name="csrf-token"]').attr('content');

The other thing to check is how you are placing that into your ajax. I find it works best when set into the ajax headers in a base file higher up than your ajax - calling the headers outside the current ajax call will usually resolve the issue of a csrf mismatch as you are having.

$.ajaxSetup({
 headers: {
    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
 }
});
Watercayman
  • 7,970
  • 10
  • 31
  • 49
1

I have solved an urgent support call! Just for a while! Maybe not the best way, but that time it worked!

First, I created a javascript function to update the token:

function renewToken() {
    var csrfUrl = $("meta[name='url_page']").attr('content') + '/refresh_csrf';

    $.get(csrfUrl, function (data) {
        $('meta[name="csrf-token"]').attr('content', data);
    });
    return;
 }

So I created this route:

Route::get('/refresh_csrf', function () {
    return response()->json(csrf_token());
})->name('csrf.renew')->middleware('auth'); /* Test */

Because, when the token expired before each new ajax request, the blade still continued having an old token. But, this function was used to update the token before each ajax request.

For example:

$(document).on('click', '.open_modal', function () {
   renewToken();
   var group_id = $(this).val();

   $.get(url + '/' + group_id, function (data) { ...
Alexandre Barbosa
  • 1,194
  • 1
  • 7
  • 6
0

Turns out there was left over line of code from a test that was refreshing the session, stupid mistake on my part.

xjx424
  • 173
  • 2
  • 12