Welcome Guest, Not a member yet? Register   Sign In
Ajax form + CSRF results in a failing request
#1

[eluser]Alhazred[/eluser]
On my site I have a form which sends the data to a controller thru an ajax request.
That did work correctly, but it stopped to work as I activated the CSRF control in the config file.

Why does it happen? How can I use the CSRF check and the ajax request together?

This is the Ajax code inside the view, with the CSRF activated it always go into the error branch, if I deactivate the CSRF check it comes back to work.
Code:
$(document).ready(function(){
  $('.ajax-loader').hide();
  $('input.add').click(function() {
   $('.ajax-loader').show();
   var form_data = {
     id: $('input#id').val(),
     tipo: $('input#tipo').val(),
     prezzo: $('input#prezzo').val(),
     inserzionista: $('input#inserzionista').val(),
     codice_sconto: $('input#codice_sconto').val()
    };
    
   $.ajax({
    url: "<?php echo site_url('carrello/add/') ?>",
    type: 'POST',
    data: form_data,
    async: false,
    success: function(msg) {
       $('#ajax_add_cart').html(msg);
      },
    error: function(xhr,textStatus, errorThrown) {
       $('#ajax_add_cart').html(textStatus);
      }
   })
   $('.ajax-loader').hide();
  });
});

This is the generated form with CSFR check activated
Code:
<form action="www.mysite.com/#.html" method="post" accept-charset="utf-8" name="addcart" id="addcart">
<div >
&lt;input type="hidden" name="csrf_test_name" value="302cb0c436a726f864dd3fc8e5a376e6" /&gt;
</div>
&lt;input type='hidden' name='id' id='id' value='1-1354017854' /&gt;
&lt;input type='hidden' name='inserzionista' id='inserzionista' value='1' /&gt;
&lt;input type='hidden' name='tipo' id='tipo' value='3' /&gt;
&lt;input type='hidden' name='prezzo' id='prezzo' value='30,18' /&gt;
&lt;input type='hidden' name='valore' id='valore' value='30,00' /&gt;
&lt;input type='button' name='add' id='add' class='add' value='Aggiungi al carrello' alt='1-1354017854' /&gt;
&lt;/form&gt;

This one with CSRF deactivated
Code:
&lt;form action="www.mysite.com/#.html" method="post" accept-charset="utf-8" name="addcart" id="addcart"&gt;
&lt;input type='hidden' name='id' id='id' value='1-1354017854' /&gt;
&lt;input type='hidden' name='inserzionista' id='inserzionista' value='1' /&gt;
&lt;input type='hidden' name='tipo' id='tipo' value='3' /&gt;
&lt;input type='hidden' name='prezzo' id='prezzo' value='30,18' /&gt;
&lt;input type='hidden' name='valore' id='valore' value='30,00' /&gt;
&lt;input type='button' name='add' id='add' class='add' value='Aggiungi al carrello' alt='1-1354017854' /&gt;
&lt;/form&gt;
#2

[eluser]apodner[/eluser]
I could be wrong, but your form_data does not appear to contain the csrf token as a element, and it is therefore not going into the POST when your ajax call is made to the carrell/add script.

Try adding the token:

Code:
var form_data = {
     id: $('input#id').val(),
     tipo: $('input#tipo').val(),
     prezzo: $('input#prezzo').val(),
     inserzionista: $('input#inserzionista').val(),
     codice_sconto: $('input#codice_sconto').val(),
     csrf_test_name: $('input#csrf_test_name').val()
    };

I think this would work too and would push all form elements into POST at once:

Code:
var form_data = $("#addcart").serialize()

hope this gets you heading in the right direction
#3

[eluser]TunaMaxx[/eluser]
This post by Jerel Unruh saved my sanity on this exact problem:

&middot; A simple solution to CodeIgniter CSRF protection and Ajax

You have to send the CSRF field value with your AJAX request or the POST request is rejected by CI as invalid. While your form is including it in a hidden field, that value is not being posted with your javascript request.

Either manually modify every AJAX call you to include the 'csrf_test_name' filed and the 'csrf_cookie_name' value, or use this jQuery plugin and set a small bit of javascript on any AJAX enable page:

&middot; jQuery-Cookie

The javascript to include on AJAX enabled pages (or in a site wide header for instance) is something like:

Code:
$(function($) {
    // this bit needs to be loaded on every page where an ajax POST may happen
    $.ajaxSetup({
        data: {
            csrf_test_name: $.cookie('csrf_cookie_name')
        }
    });
});

Just remember that the 'csrf_test_name' and 'csrf_cookie_name' in the javascript must match the following values in config.php:

Code:
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
#4

[eluser]Alhazred[/eluser]
Thank you TunaMaxx, that solved the problem.




Theme © iAndrew 2016 - Forum software by © MyBB