Tokenmismatchexception after any ajax error on Laravel 5.1

Asked

Viewed 355 times

2

I have been working with Laravel for a short time and am having a problem when using ajax requests. When my application returns any error and I try to send another request, Laravel sends me this error:

TokenMismatchException in VerifyCsrfToken.php line 53:

If I update the page (with the error of my corrected code), it no longer sends this message. It could be any server-side error like missing variable, spelling, files, anything, that in the next request regardless of the route I take it will return the above error.

Someone knows how to fix this?

2 answers

3

Just complementing @Wallace Maxters' reply.

If there is no need to use CSRF protection anywhere in the project, you can disable this option completely by changing the file app/Http/Kernel.php and removing the middleware \App\Http\Middleware\VerifyCsrfToken

Remembering that doing this you will no longer be protected against CSRF, if you need to keep the @Wallace Maxters response is the most suitable.

More information:

https://laracasts.com/discuss/channels/general-discussion/l5-avoiding-csrf-middleware-on-api-post-routes

  • yes I already knew about it. in the documentation of Laravel has this information.

2


I believe that you can solve this in the following way:

  • Display the token in an attribute of a DOM element
  • Capture this DOM token value in each ajax request and send it as the value _token.

So it could be done more or less like this:

<body data-token="{{ csrf_token() }}"></body>

In ajax:

$.ajax({
    data: {..., _token: $('body').data('token') }
});

Another way to configure your ajax requests (and I think it’s the most feasible) is by using the function $.ajaxSetup, for all requests to inherit the header with the token. So:

$.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('body').data('token')
        }
  });

In the archive VerifyCsrfToken.php, you will need to add this method:

protected function tokensMatch($request)
{

    if ($request->ajax()) {

       $token = $request->input('_token');

    } else {

       $token = $request->header('X-CSRF-Token');

    }

    return $request->session()->token() == $token;
}

Disabling the Token

If you want to disable token checking on ajax requests (which I don’t consider anything safe), you can do it as follows:

protected function tokensMatch($request)
{

    if ($request->ajax()) return true;        

    return $request->session()->token() == $token;
}
  • Whenever I request an AJAX I already send an element {_token:token} so this wouldn’t be the mistake. If I put the 1st version of the function in the file it does not accept the first request and the 2nd version is totally unfeasible because it leaves the CSRF-Token security logic

  • 1

    @Leandroluk, you’ll have to refresh the token then, huh!

  • How can I make that refresh? Because the page has not been reloaded, so there is no way to make this request... unless I create a method only to "call new token" and update the variable if you need to

  • 2

    Weird @Leandroluk is that I’m seeing several posts that were given as solved the way I did.

  • 1

    @Leandroluk, by logic, really the token should update from time to time. But this does not mean that it updates to each request. Maybe it’s another factor influencing the error

  • 1

    @Leandroluk, but you have to edit the class referring to the token. It is not simply putting the token in the ajax request (in case you set the token as the request parameter). And you could also set the token header by jQuery, so you don’t have to put the token all the time.

  • So you think the best method would be for me to generate an array to retrieve this token (from time to time) and refresh my page?

  • Definitely not @Leandroluk. Is your code in some git repository or something? I’d like to take a closer look :)

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.