Codeigniter CSRF valid for only one ajax request

I want to upload an image to the server on a jQuery change event, but using codeigniter csrf. I can upload an image only once. How can I upload images using ajax for multiple requests. Please keep in mind when I install this

config['csrf_protection'] = FALSE; 

then I can send some jQuery onchange requests, but when csrf_protection is false, I think there is no advantage of csrf. so the question is how can I send multiple requests using ajax while csrf_protection is allowed. My jquery code is as follows

 $("#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); } }); }); 
+10
source share
7 answers

In my opinion, you should try to recreate your csrf token every request

Try this sample code ...

For JS function

 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(); var dataJson = { [csrfName]: csrfHash, id: "hello", link: link }; $.ajax({ url : "<?php echo base_url('main/test'); ?>", type: 'post', data: dataJson, success : function(data) { csrfName = data.csrfName; csrfHash = data.csrfHash; alert(data.message); } }); }); 

and for the 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); } 

Let me know and good luck

Note. When someone asks you to publish more data on a question, do not publish it as a comment or answer, it is better to edit the question itself and add material.

+13
source

You can set this in config.php

 $config['csrf_regenerate'] = FALSE; 

therefore, csrf protection is valid for the entire session, and this will solve your problem. If you set $config['csrf_regenerate'] = true; then CI generates a new csrf token for each request so that your old csrf token does not match the new generated csrf token

+5
source

All you have to do is reload the SCRF token in the AJAX response. It's simple!

+1
source

$config['csrf_regenerate'] = TRUE;

leave automatic generation true, it will be more secure. In a similar case, when csrf expired in the first request. What i have implemented

 $(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 each ajax response, we send csrf data in which the latest csrf data will be replaced by the current

Request response example

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

I am updating the csrf token in every ajax request. Also, do not select this method if you are working in a multi-tabbed environment.

+1
source

add this to the js file that loads on every page (I put this at the end of jquery.js)

  $.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(); } }); 

(note that in every ajax request you cannot send empty data)

"csrf_cookie_name" at the top is defined in config.php

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

Please try as my code. it works my application

your view file

 $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; ?>" /> 

after setting jquery post method as below

 // 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); } ); }); 

please install your controller as below

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

First of all, the code recreates your csrf token every request.

0
source

Change configuration:

 $config['csrf_exclude_uris'] = ['controller/method']; 

The array can include all the white controllers / methods that you want to disable to protect csrf.

The array can also handle regular expressions, such as:

 $config['csrf_exclude_uris'] = array( 'api/record/[0-9]+', 'api/title/[az]+' ); 

For more information, visit the Codeigniter Documentation - Security Class

-1
source

All Articles