Ajax causes error 419 to be returned despite the correct token in Laravel

I have a bunch of POST requests made with Ajax in my Laravel application.

A typical query looks like this:

$.ajax({
    url: '/path/to/method',
    data: {'id': id},
    type: 'POST',
    datatype: 'JSON',
    success: function (response) {
        //handle data
    },
    error: function (response) {
        //handle error
    }
});

I have a set of CSRF tokens and everything works fine:

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

However, after a long break (for example, the computer falls asleep for a long time), all Ajax calls return error 419, as if the token had not been set. After reloading the page, everything returns to normal. This is located on the local server.

How do i solve this? Is there a way to “refresh” a token before a call? Do I need to make a bit $.ajaxSetupbefore every call? Is this not enough to do it once at page load?

+4
source share
1 answer

This is my suggestion:

Js

   //create a function to set header
    function setHeader(data){
        $.ajaxSetup({
            headers: {
               'X-CSRF-TOKEN': data
             }
         });
    }
   //in first load of the page set the header
    setHeader($('meta[name="csrf-token"]').attr('content'));

   //create function to do the ajax request cos we need to recall it when token is expire
    function runAjax(data){
      $.ajax({
         url: '/path/to/method',
         data: {'id': id},
         type: 'POST',
         datatype: 'JSON',
         success: function (response) {
            //handle data
         },
         error: function (jqXHR, textStatus, errorThrown) {
             if(jqXHR.status==419){//if you get 419 error which meantoken expired
                refreshToken(function(){refresh the token
                    runAjax();//send ajax again
                });
             }
         }
     });
    }

   //token refresh function
    function refreshToken(callback){
          $.get('refresh-csrf').done(function(data){
             setHeader(data);
              callback(true);
           });
    }
    //Optional: keep token updated every hour
     setInterval(function(){
            refreshToken(function(){
                    console.log("Token refreshed!");
                });

            }, 3600000); // 1 hour 

//route to get the token
Route::get('refresh-csrf', function(){
    return csrf_token();
});

, .

+2

Source: https://habr.com/ru/post/1695208/


All Articles