laravel TokenMismatchException in ajax request

31,320

Solution 1

There is a tip in the Laravel docs on how to do this. This might not have been available at the time of the question, but I thought I would update it with a answer.

http://laravel.com/docs/master/routing#csrf-x-csrf-token

I have tested the meta tag method from the documentation and got it working. Add the following meta tag into your global template

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

Add this JavaScript that sets defaults for all ajax request in jQuery. Preferably in a js file that is included across your app.

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

This token can exist in the request header or the form. This populates it into the request header of every ajax request.

Solution 2

You have to insert a hidden input with the _token and later get that value as you do to get the other form fields in your ajax post.

<input type="hidden" name="_token" value="{{ csrf_token() }}" />

An another method,

On your view you can set an object with the _token

<script type="text/javascript">
    var _globalObj = {{ json_encode(array('_token'=> csrf_token())) }}
</script>

and later on your ajax call you can get the _token from the object like this:

var token = _globalObj._token;

and include it on your ajax post.

Solution 3

Just do simple thing as i have shown in following code,

    $.ajax({
        type: 'POST',
        url: 'your-post-route-url',
        data: {
            "_token": "{{ csrf_token() }}",
            "form_data": $('#Form').serialize(),
        },
        success: function (data) {
            console.log(data);
        },
        error: function (reject) {
            console.log(reject);
        }
    });

I hope this one is the easiest way to solve this problem without any hidden field and it works for me in laravel 5.4 version :)

Hope it helps.

Solution 4

You can as well add the url thats giving you the error inside the VerifyCsrfToken.php file in the

protected $except = [
    //
]

Let's say your route is post. You can just add in like this

protected $except = ['post',
    //
];`... 

Hope this helps others.

Solution 5

  <html>
  <head>
  <title>Ajax Example</title>
      <meta name="csrf-token" content="<?php echo csrf_token() ?>" />    
  <script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js">
  </script>

  <script type="text/javascript">
        $.ajaxSetup({
          headers: {
              'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
          }
        });
  </script>

  <script>
     function getMessage(){
        $.ajax({
           type:'POST',
           url:'/getmsg',
           data:'_token = <?php echo csrf_token() ?>',
           data:'',
           success:function(data){
              $("#msg").html(data.msg);
           }
        });
     }
  </script>
  </head>

  <body>


  <div id = 'msg'>This message will be replaced using Ajax. 
     Click the button to replace the message.</div>
  <?php
     echo Form::button('Replace Message',['onClick'=>'getMessage()']);
  ?>
  </br>


  </body>

  </html>

and VerifyCsrfToken.php file add this function

protected function tokensMatch($request)
{
    // If request is an ajax request, then check to see if token matches token provider in
    // the header. This way, we can use CSRF protection in ajax requests also.
    $token = $request->ajax() ? $request->header('X-CSRF-Token') : $request->input('_token');

    return $request->session()->token() == $token;
}
Share:
31,320
DolDurma
Author by

DolDurma

Updated on April 25, 2020

Comments

  • DolDurma
    DolDurma about 4 years

    i'm using resource group and use this filter to resolve TokenMismatchException problem:

    Route::filter('csrf', function($route, $request) {
        if (strtoupper($request -> getMethod()) === 'GET') {
            return;
            // get requests are not CSRF protected
        }
    
        $token = $request -> ajax() ? $request -> header('X-CSRF-Token') : Input::get('_token');
    
        if (Session::token() != $token) {
            throw new Illuminate\Session\TokenMismatchException;
        }
    });
    

    my route :

    Route::group(array('prefix'=> 'admin', 'before' => 'csrf'), function(){
        Route::resource('profile' , 'ProfileController', array('as'=>'profile') );
    });
    

    now. i get error to Ajax requests such as this code:

    <script type="text/javascript">
        $(document).ready(function() {
           $('#frm').submit(function(e){
               e.preventDefault();
               name         = $('#name').val();
               family       = $('#family').val();
               email        = $('#email').val();
               currPassword = $('#currPassword').val();
               password     = $('#password').val();
               password_confirmation = $('#password_confirmation').val();     
    
               $.post("{{ route('admin.profile.update', $profile->id) }}",
                    { 
                      _method : 'PUT',
                      name                  : name,
                      family                : family,
                      email                 : email,
                      currPassword          : currPassword,
                      password              : password,
                      password_confirmation : password_confirmation  
                    },
                    function(data)
                    {
                        alert(data.errors.name);
                    },'json');
                    return false;
           });
    });
    </script>
    

    ERROR:

    {"error":{"type":"Illuminate\\Session\\TokenMismatchException","message":"","file":"\/var\/www\/alachiq\/app\/filters.php","line":83}}
    

    i think i'm must be sent _token in $.post. but i can not get input tag with name attribute. iget this error:

    TypeError: 'stepUp' called on an object that does not implement interface HTMLInputElement.