0

I get a TokenMismatchException error only when I submit a form with an ajax call? If I don't use an Ajax call I don't get the error.

What is causing this?

Laravel 5.4

I have this in the head of my app.blade.php:

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

My ajax.js

$( document ).ready(function() {
    // storing comments
    $('#storeComment').on('submit', function(e) {
        e.preventDefault();

        $.ajax({
            method: 'POST',
            url: '/comments',
            data: {},
            success: function(response){
                console.log(response);
            },
            error: function(jqXHR, textStatus, errorThrown) { 
                console.log(JSON.stringify(jqXHR));
                console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
            }
        });
    });
});

I also use the bootstrap.js that automatically registers the value of the csrf-token meta tag with the Axios HTTP library. As explained in the Laravel documentation.

Controlle Method:

public function store(CommentRequest $request)
{
    $comment = Auth::user()->comments()->save(new Comment($request->all()));

    $response = array(
        'status' => 'success',
        'comment' => $comment
    );

    return response()->json($response);
}
Priyanka khullar
  • 509
  • 1
  • 5
  • 25
Michael
  • 556
  • 1
  • 8
  • 27

5 Answers5

1

Add the token to the ajax's data :

$.ajax({
type: 'POST',
 ......
data: {'_token': '{{ csrf_token() }}'},
........
Tania Petsouka
  • 1,388
  • 1
  • 9
  • 20
  • This still causes a TokenMisconception (same error) – Michael Oct 09 '18 at 11:45
  • Do you use your meta's token to ajax headers? See here https://stackoverflow.com/questions/32738763/laravel-csrf-token-mismatch-for-ajax-post-request at zarpio's answer. – Tania Petsouka Oct 09 '18 at 11:55
1

Instead of calling jQuery you can call Axios directly and have this automatic csrf injection, with the following code:

var data = ['name' => 'Nikola', 'lastName' => 'Gavric'];
axios.post('/comments', data).then(function(response) {
    console.log(response);
});

EDIT: Complete example for axios is

$('#storeComment').on('submit', function(e) {
    e.preventDefault();

    // Retrieve form data
    var temp = [];
    var data = $(this).serializeArray();
    $.each(data, function(index, field) {
        temp[field.name] = field.value;
    });

    // Post request with temp as data
    axios.post('/comments', temp).then(function(data) {
        console.log(data); 
    });
});

And this is the code for jQuery, use whichever approach you like better:

    $.ajax({
        method: 'POST',
        url: '/comments',
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        },
        data: {
            'name': 'Nikola',
            'lastName': 'Gavric'
        },
        success: function(response){
            console.log(response);
        },
        error: function(jqXHR, textStatus, errorThrown) { 
            console.log(JSON.stringify(jqXHR));
            console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
        }
    });
Nikola Gavric
  • 3,507
  • 1
  • 8
  • 16
0
$.ajax({
          type: 'POST',
          ........
            headers: {
                 'X-CSRF-TOKEN': '{{ csrf_token() }}'
           }    
         ...........
  });

try this...

Parth kharecha
  • 6,135
  • 4
  • 25
  • 41
0

Add csrf-token to head of your application :

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

then :

$.ajax({
  url: '/some/url',
  type: 'POST',
  headers: {
    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
  },
  success: function(res){
      // Your result
      console.log(res);
  }
});
Gammer
  • 5,453
  • 20
  • 78
  • 121
-1

You can try to disable CSRF verification on specific route in App\Http\Middleware\VerifyCsrfToken.php

 protected $except = ['/comments'];
qqmydarling
  • 167
  • 1
  • 7
  • 16
  • 1
    Do not disable csrf protection, find the underlying cause for the token error. – Devon Bessemer Oct 09 '18 at 11:53
  • Devon I don't know if you are aware that the call question owner asked for is obviously an API call. API calls by default should be put inside of CSRF exclusion, can you please elaborate your downvotes. Thanks – Nikola Gavric Oct 09 '18 at 12:04
  • The reason for this is whoever is using your API doesn't know CSRF token and doesn't have to know it, thus all API urls are excluded from the CSRF checks – Nikola Gavric Oct 09 '18 at 12:07
  • @NikolaGavric, I do not see anywhere that this is an "api" call. No api token is being passed. All post requests need some sort of token to prevent CSRF attacks. – Devon Bessemer Oct 09 '18 at 13:10
  • I do because he is not serving any HTML content, but rather `application/json` which indicates it's an `ajax` call which further indicates it must be an `API` call and not a `web` call @Devon – Nikola Gavric Oct 09 '18 at 13:12
  • @NikolaGavric that makes no difference in this context. The fact that the user is not passing any token suggests they are using an authenticated session. APIs still require a token. Otherwise an attacker can force them to post comments on their behalf by posting to the same url with xss or from another site. – Devon Bessemer Oct 09 '18 at 13:15