2012-06-29 73 views
5

Estoy tratando de pasar algunos datos a mi Controlador, pero obtengo un error de 500. Después de algunas investigaciones, descubrí que se debe a que el token CSRF no se envió.Cómo incluir CSRF de Codeigniter en datos ajax

Parece que necesito incluir esto junto con los datos: <?php echo $this->security->get_csrf_token_name(); ?>:"<?php echo $this->security->get_csrf_hash(); ?>"

Mi JS es bastante débil, así que estoy un poco confundido sobre cómo modificar esto para incluir todo lo anterior.

<script type="text/javascript"> 
$(document).ready(function() { 
    $("#order").sortable({ 
     update : function (event, ui) { 
      order = $('#order').sortable('serialize'); 
      $.ajax({ 
       url: "<?=base_url().'admin/category/update_order'?>", 
       type: "POST", 
       data: order, 
       success: function(response){ 
        console.log(response); 
       } 
      }); 
     } 
    }); 
} 
); 
</script> 

Respuesta

3

El token debe ser aprobada en el argumento de data$.ajax.

Esto debería funcionar, pero vea mis notas a continuación.

order['<?php echo $this->security->get_csrf_token_name(); ?>'] = '<?php echo $this->security->get_csrf_hash(); ?>';

Sin embargo, hay algunas malas prácticas pasando aquí. Principalmente no deberías usar PHP en tu javascript porque esto evita que puedas acceder a javascript como un archivo separado (esto es bueno porque los navegadores lo almacenarán en caché para que tu página se cargue más rápido y consuma menos ancho de banda).

Es mejor almacenar el token en su pedido <form> html como esto ..

<input type="hidden" name="<?php echo $this->security->get_csrf_token_name(); ?>" value="<?php echo $this->security->get_csrf_hash(); ?>" />

Luego se obtendrán en serie con el resto de los datos del formulario.

También puede almacenar la URL en el atributo de acción del formulario. Esto ayudará a su guión con gracia degrada y también mantiene la URL en un solo lugar en vez de 2.

<form id="order" method="post" action="<?=base_url()?>admin/category/update_order"> 

En la llamada $.ajax, usar algo como esto url: $('#order').attr('action'), #order suponiendo que es la forma de identificación real.

+0

Lo siento, no incluyeron este, pero el script no usa un formulario. Reordena los elementos en una lista en cada cambio de posición. Estoy seguro de que esto será útil cuando los use. ¡Gracias! – Motive

+0

Ah, ya veo. Editado en una solución php + js. – jchook

1

Es correcto, solo agregue el token CSRF a los datos de su publicación. Puede utilizar la función $ .extend de jQuery para fusionar el objeto orden que ya ha creado con los datos token CSRF, así:

$.extend(alerts, { 
'<?php echo $this->security->get_csrf_token_name(); ?>' : 
'<?php echo $this->security->get_csrf_hash(); ?>' }); 
0

que se extienden form_helper como MY_form_helper.php para servir fichas CSRF a mi propio código de forma generación - que podría utilizar algo similar: tiendas

function secure_form() { 
     $CI =& get_instance(); 
     return '<input type="hidden" name='.$CI->security->get_csrf_token_name().' value='.$CI->security->get_csrf_hash().'>'; 
    } 
2

CI CSRF en galleta y se puede recuperar a partir de ahí:

var csrf = $.cookie('csrf_cookie_name'); 

La desventaja de este método es que jQuery no proporciona acceso de cookies de forma nativa. Por lo tanto, necesitará un jquery plugin.

0

otra solución es utilizar .serialize():

$.post("user/save", $('#frmUser').serialize(),function(html){ 
     $("#results").html(html); 
}); 

que se encuentra el campo oculto que almacena los datos CSRF.

1

Aquí hay un enfoque diferente. Función simple en Auth.php que devuelve el nombre del token csrf y el hash en formato JSON.Luego, en nuestro javascript, haga dos llamadas ajax, la primera en tomar las credenciales csrf e insertarlas en campos ocultos, la segunda para manejar nuestro formulario actual.

// función lugar en el controlador auth.php

public function get_csrf() 
{ 
    $csrf['csrf_name'] = $this->security->get_csrf_token_name(); 
    $csrf['csrf_token'] = $this->security->get_csrf_hash(); 

    echo json_encode($csrf); 
} 

// myFunction()

<script type="text/javascript"> 
function myFunction() { 

    // first ajax call to grab the csrf name and token 
    // from our get_csrf() function in Auth.php 
    $.ajax({ 
     type: "GET", 
     dataType: 'json', 
     url: "https://<your_domain>.com/auth/get_csrf", //replace with your domain 
     success: function (data) { 

      // assign csrf name and token to variables 
      csrf_name = data.csrf_name; 
      csrf_token = data.csrf_token; 

      // assign field1 and field2 field values to variables 
      var form_field1 = document.getElementById('field1').value; 
      var form_field2 = document.getElementById('field2').value; 

      // insert csrf creds into form 
      $('#csrftoken').attr('name', csrf_name); 
      $('#csrftoken').val(csrf_token); 

      // second ajax call -- this is our form handler 
      $.ajax({ 
       type: "POST", 
       url: "https://<your_domain>.com/<your_controller>/<your_function>", //replace with your domain/controller/function 
       data: { 
        // ES6 computed property keys are great... 
        [csrf_name] : csrf_token, 
        "field1" : form_field1, 
        "field2" : form_field2 
         }, 
       success: function(data) { 

        // handle the return from your form submit 
        if (data == "ok") { 
         console.log("Success!"); 
         $("#infoMessage").html("<p>Success</p>").fadeIn(300); 

        } else { 

         console.log("Oops!"); 
         $("#infoMessage").html("<p>Oops!</p>"); 

        } 

       } 
      }); 

     } 
    }); 

} 
</script> 

// html

<div id="infoMessage"></div> 

<form method="post" accept-charset="utf-8"> 

    <input type="hidden" id="csrftoken" name="" value="" /> 

    <label for="field1">Field 1:</label> <br /> 
    <input type="text" name="field1" id="field1" /> 

    <label for="field2">Field 2:</label> <br /> 
    <input type="text" name="field2" id="field2" /> 

    <input type="button" name="submit" value="SUBMIT" onclick="myFunction()" /> 

</form>