wake-up-neo.net

Codeigniter CSRF ist nur für eine Ajax-Anforderung gültig

Ich möchte ein Bild auf dem Server bei einem Änderungsereignis von jQuery hochladen, aber mit dem Codeigniter csrf kann ich ein Bild nur einmal hochladen. Wie kann ich Bilder mit ajax für mehrere Anfragen hochladen? Bitte beachten Sie, wenn Sie dies einstellen

config['csrf_protection'] = FALSE;

dann kann ich mehrere Request-jQuery-Onchange-Ereignisse senden, aber wenn csrf_protection falsch ist, denke ich, dass es keinen Vorteil von csrf gibt. Die Frage ist also, wie ich mit ajax mehrere Anforderungen senden kann, während csrf_protection aktiviert ist. Mein Jquery-Code folgt

$("#avatar").change(function(){
    var link = $("#avatar").val();     
    $.ajax({
        url : "<?php echo base_url('main/test'); ?>",
        type: 'post',
        data: {'<?php echo $this->security->get_csrf_token_name(); ?>':'<?php echo $this->security->get_csrf_hash(); ?>',"id":"hello","link":link},            
        success : function(data)
        {   
            alert(data);
        }  
    });
});
7
romio

Meiner Meinung nach sollten Sie versuchen, bei jeder Anforderung Ihr CSRF-Token neu zu erstellen

Probieren Sie dieses Codebeispiel aus ...

Für die js funcion

var csrfName = '<?php echo $this->security->get_csrf_token_name(); ?>',
    csrfHash = '<?php echo $this->security->get_csrf_hash(); ?>';
("#avatar").change(function(){
    var link = $("#avatar").val();

    $.ajax({
        url : "<?php echo base_url('main/test'); ?>",
        type: 'post',
        data: {csrfName:csrfHash,"id":"hello","link":link},            
        success : function(data)
        {   
            csrfName = data.csrfName;
            csrfHash = data.csrfHash;
            alert(data.message);
        }  
    });
});

und für den Controller

public function test() { 
    $config['upload_path'] = './uploads/'; 
    $config['allowed_types'] = 'gif|jpg|png'; 
    $config['max_size'] = 500; 
    $config['max_width'] = 260; 
    $config['max_height'] = 260; 

    $reponse = array(
                'csrfName' => $this->security->get_csrf_token_name(),
                'csrfHash' => $this->security->get_csrf_hash()
                )

    $this->load->library('upload', $config); 
    if (!$this->upload->do_upload('link')) { 
        $reponse['message'] = "error"; 
    } 
    else { 
        $data = array('upload_data' => $this->upload->data()); 
        $image_name = $data['upload_data']['file_name']; 
        $reponse['message'] = $image_name; 
    } 

    echo json_encode($reponse);
}

Lass es mich wissen und viel Glück

Hinweis: Wenn Sie von jemandem nach mehr Daten gefragt werden, stellen Sie diese nicht als Kommentar oder Antwort. Es ist besser, die Frage selbst zu bearbeiten und das Zeug hinzuzufügen

10
Edu

Sie können dies in der config.php einstellen 

$config['csrf_regenerate'] = FALSE;

der csrf-Schutz ist also während der gesamten Sitzungszeit gültig, mit der Ihr Problem gelöst wird. Wenn Sie $config['csrf_regenerate'] = true; einstellen, generiert CI bei jeder Anforderung ein neues csrf-Token, sodass Ihr altes csrf-Token nicht mit der neu generierten csrf übereinstimmt Zeichen 

4
Brian85

Sie müssen lediglich das CSRF-Token in Ihrer Antwort AJAX erneut laden. So einfach ist das!

1
Brian85

$config['csrf_regenerate'] = TRUE;

halten Sie die automatische Generierung auf true, um die Sicherheit zu erhöhen. In einem ähnlichen Fall, wenn csrf in der ersten Anforderung abgelaufen ist. Was ich umgesetzt habe

$(document).ajaxComplete(function (event, xhr, settings) {
 let response = xhr.responseText,
 let obj = JSON.parse(response),
 let csrfData = obj.csrf;
 document.querySelector('input[name="' + csrfData.name + '"]').value = csrfData.hash; 
}); //Also here you can update any other non input element    

In jeder Ajax-Antwort übergeben wir CSRF-Daten, in denen die neuesten CSRF-Daten durch die aktuellen ersetzt werden

Musterantwort von Anfrage

{ 
csrf : {
  name : 'csrf_name',
  hash : 'qw76sd7s6f78sdfs8dfs9df8cx9'
 }
}

Ich aktualisiere das csrf-Token in jeder Ajax-Anforderung. Wählen Sie diese Methode auch nicht, wenn Sie mit einer Umgebung mit mehreren Registerkarten arbeiten

1

fügen Sie dies in einer js-Datei hinzu, die jede Seite geladen wird (ich setze dies am Ende von jquery.js ein)

    $.ajaxSetup({
        beforeSend:function(jqXHR, Obj){
            var value = "; " + document.cookie;
            var parts = value.split("; csrf_cookie_name=");
            if(parts.length == 2)   
            Obj.data += '&csrf_token='+parts.pop().split(";").shift();
        }
    });

(Beachten Sie, dass Sie in jeder Ajax-Anfrage keine leeren Daten zum Senden haben können.)

"csrf_cookie_name" oben in config.php definiert 

$config['csrf_cookie_name'] = 'csrf_cookie_name';
0

Jedes Mal, wenn Sie eine Anfrage stellen, wird die csrf_token wird aktualisiert von CI . Deshalb funktioniert die Funktion CSRF nur einmal. Jedes Mal, wenn wir eine Anfrage stellen, müssen wir auch das csrf_token aktualisieren. Ich löse dieses Problem, indem ich das tue.

Conroller: Mit diesem Code wird die aktualisierte csrf abgerufen .

public function update_csrf()
{
  $data['csrf_hash'] = $this->security->get_csrf_hash();
  echo json_encode($data);
}

AJAX : Ersetzen Sie den alten Wert Ihres csrf = name="csrf_token_name"

var jqXHR = $.ajax({
            url: $(this).attr('action'),
            type: 'POST',
            data: $(this).serialize(),
            dataType: 'json',
        })
        jqXHR.done(function(response) {
            $('input[name=csrf_token_name]').val(response.csrf_hash); //update the csrf to the form 
        })
        jqXHR.fail(function(jqXHR, textStatus, errorThrown) {
            console.log(jqXHR);
            console.log(textStatus);
            console.log(errorThrown);
        });

Wichtig !: benutze dataType: 'json'

Jedes Mal, wenn Sie eine erfolgreiche Anfrage haben, wird der csrf_token wird ebenfalls aktualisiert und Sie sind jetzt frei von 403 (Forbidden) error.

0
curiosity

Bitte versuchen Sie es mit meinem Code. Es ist meine Anwendung

ihre Ansichtsdatei

$token_name = $this->security->get_csrf_token_name();
$token_hash = $this->security->get_csrf_hash();

<input type="text" id="search-text" name="parent_name" placeholder="Search" value=""  >
<input type="hidden" id="csrf" name="<?php echo $token_name; ?>" value="<?php echo $token_hash; ?>" />

nach der set-Jquery-Post-Methode wie folgt

// Get Keyup 
jQuery( "#search-text").keyup(function() {
    // Get Data 
    var val       = jQuery("#search-text").val();
    var hashValue = jQuery('#csrf').val();

    // Get jquery post for ajax task
    jQuery.post( 
        '<?php echo $base_controler; ?>',
        {val:val,'<?php echo $this->security->get_csrf_token_name(); ?>':hashValue}, 
        function(data)
        { 
            // Get return data to decode
            var obj = jQuery.parseJSON(data);
            // Get csrf new hash value
            var new_hash = obj.csrfHash;
            // Set csrf new hash value update
            jQuery('#csrf').val(new_hash);

        }
    );        

});

bitte stellen Sie Ihren Controller wie folgt ein

$reponse = array(
        'csrfName' => $this->security->get_csrf_token_name(),
        'csrfHash' => $this->security->get_csrf_hash()
        );
echo json_encode($reponse);

vor allem Code erstellen Sie Ihre csrf-Token für jede Anforderung neu.

0
Md Suzon Mia