Search code examples
jqueryajaxlaravellaravel-5jquery-post

jQuery add CSRF token to all $.post() requests' data


I am working on a Laravel 5 app that has CSRF protection enabled by default for all POST requests. I like this added security so I am trying to work with it.

While making a simple $.post() request I received a 'Illuminate\Session\TokenMismatchException' error because the required form input _token was missing from the POST data. Here is an example of a $.post request in question:

var userID = $("#userID").val();
$.post('/admin/users/delete-user', {id:userID}, function() {
// User deleted
});

I have my CSRF token stored as a meta field in my header and can easily access it using:

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

Is it possible to append this to the json data on all outgoing $.post() requests? I tried using headers but Laravel did not seem to recognize them -

var csrf_token = $('meta[name="csrf-token"]').attr('content');
alert(csrf_token);
$.ajaxPrefilter(function(options, originalOptions, jqXHR){
    if (options['type'].toLowerCase() === "post") {
        jqXHR.setRequestHeader('X-CSRFToken', csrf_token);
    }
});

Solution

  • Your $.ajaxPrefilter approach is a good one. You don't need to add a header, though; you simply need to add a property to the data string.

    Data is provided as the the second argument to $.post, and then formatted as a query string (id=foo&bar=baz&...) before the prefilter gets access to the data option. Thus, you need to add your own field to the query string:

    var csrf_token = $('meta[name="csrf-token"]').attr('content');
    $.ajaxPrefilter(function(options, originalOptions, jqXHR){
        if (options.type.toLowerCase() === "post") {
            // initialize `data` to empty string if it does not exist
            options.data = options.data || "";
    
            // add leading ampersand if `data` is non-empty
            options.data += options.data?"&":"";
    
            // add _token entry
            options.data += "_token=" + encodeURIComponent(csrf_token);
        }
    });
    

    This will turn id=userID into id=userID&_token=csrf_token.