-
june123
Junior Member
-
Posts: 27
Threads: 9
Joined: Jun 2016
Reputation:
0
I am using CI3.
When I set $config['csrf_regenerate'] = TRUE;, after the first request, subsequent ajax requests fail.
This is obviously because of the csrf token being regenarated after every request.
In the header.php page, I am using
Quote:<script type="text/javascript" language="javascript">
var csfrData = {};
csfrData['<?php echo $this->security->get_csrf_token_name(); ?>'] = '<?php echo $this->security->get_csrf_hash(); ?>';
</script>
Then there is a csrfload.js page, where I am using ajaxSetup function to send the token with every request..
Quote:$(function() {
// Attach csfr data token
$.ajaxSetup({
data: csfrData
});
});
Now how do I change this code to include csrf token generation with every request? Also, setting csrf_regenerate as TRUE may give problem is multiple tabs/windows ?
-
june123
Junior Member
-
Posts: 27
Threads: 9
Joined: Jun 2016
Reputation:
0
(07-27-2017, 05:52 AM)Martin7483 Wrote: Return the new CSRF token in your response and update the CSRF variable in your JavaScript.
Remember to always include the CSRF token no matter the status of execution. Both success and fails should return the new CSRF token.
Martin, can you please show this with the code i have posted?
I am not using concurrent requests, one request at a time will do.
-
Martin7483
Crossfire CMS
-
Posts: 373
Threads: 14
Joined: Sep 2015
Reputation:
20
First I'm asuming you are using jQuery
Your AJAX code should have a success and error handler for responses.
The controller/method that is called via the AJAX could respond with JSON output
Code: $.ajax({
type: "POST",
dataType: "json",
url: 'http://www.somewebsite.com/some-controller/some-method',
data: theDataYouAreSending,
success: function(data){
// This is a success response
csfrData = {};
csfrData[data.csrfTokenName] = data.csrfTokenHash;
},
error: function(data) {
// This is a error response
csfrData = {};
csfrData[data.csrfTokenName] = data.csrfTokenHash;
}
});
In the called method you could do this
PHP Code: $response = array('success'=>TRUE/FALSE); $response['csrfTokenName'] = $this->security->get_csrf_token_name(); $response['csrfTokenHash'] = $this->security->get_csrf_hash();
header('Content-Type: application/json'); echo json_encode($response); exit;
The data argument in function(data) is an object containing what ever you added to the output
-
june123
Junior Member
-
Posts: 27
Threads: 9
Joined: Jun 2016
Reputation:
0
Thanks Martin. I am using jquery.
I am giving detailed code here:
Quote:$('#project_id').change(function() {
var project_id=$("#project_id").val();
var domain=$("#domain").val();
$.ajax({
type: "POST",
url: domain + "index.php/project/get_department",
data: {project_id: project_id},
dataType: 'json',
success:
function(j){
if(j.length >= 2) {
var options = '';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + j[i].id + '">' + j[i].name + '</option>';
}
$("#department_id").html(options);
$('#department_id option:first').attr('selected', 'selected');
}
else if (j.length == 1){
options += '<option value="' + j[0].id + '">' + '------------------------------------' + '</option>';
$("#department_id").html(options);
$('#department_id option:first').attr('selected', 'selected');
}
else{
$("#department_id").val(j[1].id);
}
}
});
});
The get_department function is below:
Quote:public function get_department()
{
$project_id = $this->input->post('project_id');
if(is_numeric($project_id) && $project_id > 0 && $project_id == round($project_id, 0)){
$sql = "SELECT department.id, department.name FROM project, department,project_dept
WHERE project.id= ? and project.id= project_dept.project_id and department.id= project_dept.department_id order by department.name";
$query = $this->db->query($sql, array($project_id));
$loop = html_escape($query->result_array());
$r[0] = "----- Select Departments -----";
foreach ($loop as $row)
$r[$row['id']] = $row['name'];
$dept = $r;
$json = '[';
$json_names = array();
foreach ($dept as $id => $name) {
$json_names[] = '{"id": "'.$id.'", "name": "'.$name.'"}';
}
$json .= implode(',', $json_names);
$json .= ']';
echo $json;
}
else
exit();
}
Now how do I incorporate your json code with this code ?
-
Martin7483
Crossfire CMS
-
Posts: 373
Threads: 14
Joined: Sep 2015
Reputation:
20
07-28-2017, 01:58 AM
(This post was last modified: 07-28-2017, 01:59 AM by Martin7483.)
First
Why don't you use the PHP function json_encode?
Your two foreach loops can be done in 1 foreach and there is no need to create a json string in that manner.
Second
I'm not going to write the code for you.
You have all the pieces of the puzzle, and it shouldn't be that hard to figure out.
Looking at your code you should be able to do it
But to help you out a bit
PHP Code: $departments = array(); foreach ($loop as $row) { $departments[] = array('id'=>$row['id'],'name'=>$row['name']); } $response['departments'] = $departments;
-
june123
Junior Member
-
Posts: 27
Threads: 9
Joined: Jun 2016
Reputation:
0
Thanks Martin for your help and giving some much needed confidence
But to be honest, I am not very good with this json/jquery stuff. Thats why I had to stitch up that weird json string. Now I have done this far:
Quote:foreach ($loop as $row)
{
$departments[] = array('id'=>$row['id'],'name'=>$row['name']);
}
$response['departments'] = $departments;
$response['csrfTokenName'] = $this->security->get_csrf_token_name();
$response['csrfTokenHash'] = $this->security->get_csrf_hash();
echo json_encode($response);
Then in ajax part:
Quote:$('#project_id').change(function() {
var project_id=$("#project_id").val();
var domain=$("#domain").val();
$.ajax({
type: "POST",
url: domain + "index.php/project/get_department",
data: {project_id: project_id},
dataType: 'json',
success:
function(j){
csfrData = {};
csfrData[j.csrfTokenName] = j.csrfTokenHash;
if(j.departments.length >=2) {
var options = '';
for (var i = 0; i < (j.departments.length-1); i++) {
options += '<option value="' + j.departments[i].id + '">' + j.departments[i].name + '</option>';
}
$("#department_id").html(options);
$('#department_id option:first').attr('selected', 'selected');
}
else if (j.departments.length == 1){
options += '<option value="' + j.departments[0].id + '">' + '------------------------------------' + '</option>';
$("#department_id").html(options);
$('#department_id option:first').attr('selected', 'selected');
}
else{
$("#department_id").val(j.departments[1].id);
}
}
});
});
Now the next combobox doesnt get populated:
Quote:$('#department_id').change(function() {
var department_id=$("#department_id").val();
var domain=$("#domain").val();
$.ajax({
type: "POST",
url: domain + "index.php/project/get_scheme",
data: {department_id: department_id},
dataType: 'json',
success:
When I checked the console in developer tools(chrome), the following msg comes:
Failed to load resource: the server responded with a status of 403 (Forbidden) get_scheme
Maybe the ajaxSetup function in csrf.js file is not sending the updated token:
$(function() {
// Attach csfr data token
$.ajaxSetup({
data: csfrData
});
});
Kindly guide.
-
Martin7483
Crossfire CMS
-
Posts: 373
Threads: 14
Joined: Sep 2015
Reputation:
20
First I spotted this on the jQuery website regarding ajaxSetup
Set default values for future Ajax requests. Its use is not recommended.
If I understand correctly, the use of this function will effect all following AJAX calls.
Once it has been declared the values are not updated.
So yes, I think this is the problem and you should not use it.
Create your own set and get functions for the CSRF
PHP Code: <script type="text/javascript" language="javascript"> var csfrData; // Declare globally csfrTokenName = '<?php echo $this->security->get_csrf_token_name(); ?>'; csfrHash = '<?php echo $this->security->get_csrf_hash(); ?>';
setCSRF(csfrTokenName, csfrHash);
function setCSRF(name, value) { csfrData = {}; // Reset csrfData to an empty array csfrData[name] = value; }
function getCSRF() { return csrfData; } </script>
And from the AJAX call you of course call the setCSRF function with the returned CSRF to update
|