15

I'm new to both Stackoverflow and Laravel 4, I am trying to submit a form through jquery ajax. I serializeArray() the form and use json to submit it. In laravel, in the routes I check the csrf token submitted, the go to my controller for process inputs. The csrf check doesn't work when the _token input is in an array as with serializeArray(). I have to get the _token value and submit is as a seperate ajax data. I'm wondering if there is a way to tell csrf filter where ever its running to check the input array for hte field _token and use that? here is my code:

routes.php

Route::post('searchAjax', array('before' => 'csrf', 
                                'uses' => 'SearchController@searchAjax'));

This is where I wan't it to read the array form[0]['_token] but I don't know how to tell it to do that.

index.js
    var form = $('#search').serializeArray();
var token = $('#search > input[name="_token"]').val();
$.ajax({
    type: 'post',
    url: 'searchAjax',
    dataType: 'json',
    data: { _token: token, form: form },
    success: function(data) {
        for(var key in data)
        {
            //alert(key)
        }
        //alert(data.message);
    }
});

I want to get rid of { _token: token, form: form } in the ajax call and just have 'form' that is an array with _token in it already. here is the html:

<form id="search" class="form-horizontal" accept-charset="UTF-8" action="http://testing:998/search" method="POST">
  <input type="hidden" value="6GBbv9LmnOdL8UcOsm8DDJ4Bfi6eGcQRlC9SPdL4" name="_token">
<div class="control-group">
  <label class="control-label" for="title">Book Titles</label>
  <div class="controls">
    <input id="title" class="input" type="text" value="click to search book titles" name="title">
  </div>
</div>
<div class="control-group">
<div class="control-group">
<div class="control-group">
</form>

Thank you in advance. :)

3
  • what is wrong with data: { _token: token, form: form } and what do you want ? Commented Dec 7, 2013 at 18:02
  • nothing is wrong with it, but form already contains _token. I was merely trying to make my code simpler and see if there is a way to access the Route:: to execute a function before and then link to a controller. Commented Dec 7, 2013 at 23:37
  • Your question is confusing, can you rephrase it ? Commented Dec 8, 2013 at 8:55

1 Answer 1

28

Another option is to use the approach outlined by Kelt Dockins which is to send the token in the headers using jquery, eg. somewhere in your jquery/javascript bootstrapping add:

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

This will get the CSRF token from a header meta data tag and include it in the headers of each ajax request. Then you need to add the metadata and token into your Laravel templates, eg.

<head>
    <title>My Page</title>
    <meta name="csrf-token" content="<?= csrf_token() ?>">

You also need to modify the CSRF filter to check the ajax request header as well the default Input::get('_token')

Route::filter('csrf', function()

{
   $token = Request::ajax() ? Request::header('X-CSRF-Token') : Input::get('_token');
   if (Session::token() != $token) {
      throw new Illuminate\Session\TokenMismatchException;
   }
});
Sign up to request clarification or add additional context in comments.

4 Comments

@Wistar the link is live again and here is the link to follow up post (you should read this too as it improves security aspect) keltdockins.com/2013/12/12/csrf-token-protection-in-laravel
@Danny I noticed. Forgot to erase my comment.
Also note the vulnerability discovered with the CSRF filter in Laravel 4: blog.laravel.com/csrf-vulnerability-in-laravel-4
Please note, all suggested links are broken.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.