CodeIgniter CSRF 403 error - javascript

I'm trying to solve this problem for a long time and stil have no clue to it.
I am trying to send and catch AJAX request within CodeIgniter framework.
PHP file with page tamplate:
<table id="jivoClients" class="display nowrap" cellspacing="0" width="100%">
<tbody>
<?php foreach($clients as $client): ?>
<td class="details-control" id="<?php echo $client["chat_id"]. ","
.$this->security->get_csrf_token_name(). ","
.$this->security->get_csrf_hash(); ?>"></td>
<th class="clientData"><?php echo str_replace(",", "<br>" , $client["visitor_info"]); ?></th>
<th class="clientData"><?php echo ($client['session_geoip_country']); ?></th>
<th class="clientData"><?php echo ($client['session_geoip_city']); ?></th>
<th class="clientData"><?php echo ($client['visitor_chats_count']); ?></th>
<th class="clientData"><?php echo ($client['agents_names']); ?></th>
<th class="clientData"><?php if(isset($client['messages']['0']['timestamp'])): ?>
<?php echo date('m/d/Y', $client['messages']['0']['timestamp']); ?>
<?php endif;?></th>
<th class="clientData"><?php if(isset($client['messages']['0']['timestamp'])): ?>
<?php echo date('H:i:s', $client['messages']['0']['timestamp']); ?>
<?php endif;?></th>
<th class="clientData"><?php if(isset($client['messages']['0']['Message'])): ?>
<?php echo ($client['messages']['0']['Message']); ?>
<?php endif;?></th>
<th class="clientData"><?php echo ($client['Manager_note']); ?></th>
</tr>
<?php endforeach; ?>
</tbody>
</table>
In my js file code looks like:
var id = $(this).attr('id');
var messageData = id.split(",");
var token = "" + messageData[1];
var post_data = {
'id' : messageData[0],
'csrf_crm' : messageData[2]
}
$.ajax({
type:'POST',
data: {
func : 'getNewLocations',
'id' : messageData[0],
'csrf_crm' : messageData[2]
},
url:'application/controllers/AjaxController.php',
success: function(result, statut) {
if (result == 'add') {
//do something
}
else if (result == 'remove') {
//do something
}
}
});
And I constantly get 403 error. As I already read on forum, it means that my CSRF token is not correct. But it seems that I get it normally (checked in debugger).
However this does not solve the problem.
Thanks in advance.

You need to do echo to assign value of php variable. Also wrap token in ''
var token = '<?php echo $this->security->get_csrf_hash() ?>'; //<----- do echo here
var id = $(this).attr('id');
$.ajax({
type:'POST',
data: {
func : 'getNewLocations',
'id' : id,
'csrf_crm' : token
},
url:'application/controllers/AjaxController.php',
success: function(result, statut) {
if (result == 'add') {
//do something
}
else if (result == 'remove') {
//do something
}
}
});

Get the csrf token value like this:
var token = $('[name="csrf_token"]').val();

Finally I solved this problem.
It appered, that I was using incorrect route in js file.
The correct sequence of actions looks like this:
1) add new line in file routes.php:
$route['jivosite/user'] = 'jivosite/user';
2) add code in js file:
post_data = JSON.stringify(post_data);
post_data = JSON.stringify(post_data);
var url = baseurl + "jivosite/user"
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.addEventListener("readystatechange", function () {
if (xhr.readyState == 4 && xhr.status === 200) {
console.log(xhr.response);
}
});
xhr.addEventListener("error", function (err) {
console.log(err);
});
xhr.send(post_data ? JSON.stringify(post_data) : null);
3) check config.php file.
$config['cookie_secure'] = FALSE; should be like this
and $config['csrf_exclude_uris'] = array('jivosite/user'); should include my route
4) create file Jivosite.php in controllers folder with contents:
class Jivosite extends CI_Controller
{
public function user()
{
$id=$this->input->post('id');
echo $id;
}
}
And it worked for me.
Thanks for all answers.

Related

How to call href function with ajax

I'm new here, i'm working with ajax and notify.js on my website.
Where there are a slight problem, which is i can't call my function using href with ajax and the notify.js won't pop up and delete the file
Let me show you my code
Views:
<tbody>
<?php foreach ($rows as $row) { ?>
<tr>
<td><?php echo $row ->description ?></td>
<td><?php echo $row->updated_at ?></td>
<td>Edit</td>
<td><a id="aDeleteOrderType" onclick="type_delete()" href="#.<?php echo $row->id ?>">Delete</a></td>
</tr>
<?php } ?>
Admin Footer
<script>
$("#aDeleteOrderType").click(function(e){
e.preventDefault();
$.ajax({
url: '<?php echo base_url().'admin/type_delete' ?>',
type: 'post',
data: {
},
success: function(msg)
{
if (msg == 'valid')
{
$.notify('Data Has Been Deleted', 'error')
}
}
});
});
Controller
public function type_delete($id)
{
$is_logged_in1 = $this->session->userdata('is_logged_in');
$type = $this->session->userdata('type');
if(!isset($is_logged_in1) || $is_logged_in1 != true)
{
$data['error'] = '';
$this->load->view('login-1', $data);
}
else
{
$this->load->model('listtipeorder_model');
$this->listtipeorder_model->delete_list_type($id);
echo 'valid';
}
}
Help me guys please:(
P.S sorry for my bad english though.
HTML:
Notice data-id, and attribute we will get soon.
<td><a id="aDeleteOrderType" href="#" data-id="<?php echo $row->id ?>">Delete</a></td>
JS:
Since you aren't using get or post to get the $id var in your php function and instead are passing it as a url param you have to do the same via jquery.
<script>
$(document).ready(function () {
$("#aDeleteOrderType").click(function (e) {
var id = $(this).attr('data-id');
e.preventDefault();
$.ajax({
url: '<?php echo base_url() . '/admin/type_delete/'; ?>' + id,
type: 'POST',
success: function (msg) {
if (msg == 'valid') {
// success would be better suited than 'error'
// might confuse some
$.notify('Item deleted', 'success');
} else {
$.notify('Error occurred', 'error');
}
}
});
});
});
</script>
PHP:
There isn't anything wrong with your PHP, but it can be improved.
function type_delete($id = null) {
$is_logged_in1 = $this->session->userdata('is_logged_in');
//$type = $this->session->userdata('type');
// isset not required with userdata as will return null if no data
if ($is_logged_in1 != true || is_null($id)) {
echo 'error';
// don't load a view
//$data['error'] = '';
//$this->load->view('login-1', $data);
} else {
$this->load->model('listtipeorder_model');
$this->listtipeorder_model->delete_list_type($id);
echo 'valid';
}
exit;
}

How to delete row after i select the row and press the button

Screenshot
<?php
if(isset($_GET['View']) && $_GET['View']=="HistoryEntry"){
echo '
<h2>History Of Entries</h2>
<table id="table" class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Date In</th>
<th scope="col">Date Out</th>
<th scope="col">Rfid</th>
<th scope="col">Plate #</th>
</tr>
</thead>
<tbody>';
global $connection;
$query = "SELECT * FROM history_entries";
$result = mysqli_query($connection, $query);
while($row = mysqli_fetch_assoc($result)){
echo '<tr>
<th scope="row">'.$row['Entry_ID'].'</th>
<td>'.$row['Date_in'].'</td>
<td>'.$row['Date_out'].'</td>
<td>'.$row['Acc_rfid'].'</td>
<td>'.$row['Plate_num'].'</td>
</tr>';
}
echo ' </tbody>
</table>
<center>
<button>Delete</button>
</center>
<div class="line"></div>';
}
?>
?>
$("#table tr").click(function() {
$('.selected').removeClass('selected');
$(this).addClass("selected");
});
$("#Sample").click(function() {
var value = $(".selected th:first").html();
value = value || "No row Selected";
});
As you can see this my codes, i already know how to select the row and get the ID but cant pass the ID "value" to php in order to do the delete function in database. can i use here $.POST function here? or is it better to use GET function here but i think it wouldn't be secure.
This is how you can do it without get param :
1/ Your FRONT :
HTML (just an example)
<table>
<tr id="row_id">
<td>Data 1</td>
<td>Data 2</td>
...
</tr>
...
</table>
<button id="delete_row" type="button">Delete</button>
JS / jQuery
var current_row_id = "";
// You select the row
$("#table tr").click(function() {
$('.selected').removeClass('selected');
$(this).addClass("selected");
current_row_id = $(this).attr("id"); // Here you get the current row_id
});
// You delete the row
$("#delete_row").on("click", function() {
$.ajax({
type: "POST",
url: "delete.php",
data: {"id" : current_row_id }, // You send the current_row_id to your php file "delete.php" in post method
dataType: 'json', // you will get a JSON format as response
success: function(response){
// you do something if it works
},
error: function(x,e,t){
// if it doesn't works, check the error you get
console.log(x.responseText);
console.log(e);
console.log(t);
}
});
});
2/ Your BACK
PHP "delete.php" file
<?php
$id = $_POST['id']; // You get the 'current_row_id' value
// Now you do your DELETE request with this id :
$sql = "DELETE ... WHERE id = :id";
etc...
$result = array(); // You can prepare your response and send information about what you did
$result['row_deleted'] = $id;
$result['message'] = "The row with id = " . $id . " was deleted with success";
$result['type'] = "success";
//etc....
echo json_encode($result); // You send back a response in JSON format
3/ Back to the FRONT
Your ajax call, the success part :
success: function(response){
// You can display a success message for example using your response :
alert(response.message); // You will get 'The row with id = {the row id} was deleted with success' here for example
},
Is it what you are looking for?
here is a simple Ajax request
var data = {
rowId: 1
};
$.ajax({
type: "POST",// GET|POST
url: 'delete.php', // Where you want to send data like url or file
data: data, // this is what you want to send to server, in this case i send data with id = 1 to server
dataType: 'json' // here we say what data type we want "json"
success: function(response) {
alert(response);
}, // this is the callback were u will get response from your server
});
delete.php here is how u can handle this ajax
$rowId = htmlspecialchars($_POST['rowId']);
if ($rowId) {
global $connection;
$query = "DELETE FROM history_entries WHERE Entry_ID = " . $rowId;
$result = mysqli_query($connection, $query);
$response = array(
'success' => true
);
echo json_encode($response);
exit;
} else {
echo json_encode(array('success' => false));
exit;
}
Hope this will help you to understand how to use Ajax

integrate ajax script in zf2 project

I want to save checkbox change using ajax.But I can't get any saved changes.
this is the view:actionacces.phtml
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
$title = 'Action \'s acces by role ';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<table class="table">
<tr>
<th>Action</th>
<?php foreach ($roles as $role) : ?>
<th><?php echo $this->escapeHtml($role['name']); ?> </th>
<?php endforeach; ?>
</tr>
<tr><?php foreach ($actions as $action) : ?>
<th> <?php echo $this->escapeHtml($action['name']);
'<\br>' ?></th>
<?php
foreach ($roles as $role) :
$exist = 0;
foreach ($acls as $acl) :
if ($acl['fk_role_id'] == $role['id'] && $acl['fk_action_id'] == $action['id'] && $acl['acces'] == 1) {
$exist = 1;
}
endforeach;
?>
<th> <?php if ($exist == 1) { ?>
<label class="css-input switch switch-sm switch-primary push-10-t">
<input type='checkbox' class="checkboxAccess" id_role="<?= $role['id'] ?>" id_action="<?= $action['id'] ?>" acces="<?= $exist ?>" checked><span></span>
</label>
<?php } else { ?>
<label class="css-input switch switch-sm switch-primary push-10-t">
<input type="checkbox" class="checkboxAccess" id_role="<?= $role['id'] ?>" id_action="<?= $action['id'] ?>" acces="<?= $exist ?>" > <span></span>
</label>
</th>
<?php }
endforeach;
?>
</tr>
<?php endforeach; ?>
</table>
this is the droit.js:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
$(document).ready(function () {
$(".checkboxAccess").on('click', function () {
// console.log($(this).attr("id_role"));
// var role_id = $(this).attr("id_role");
// var action_id = $(this).attr("id_action");
// var droit = $(this).is(':checked');
console.log($(this).attr("id_role"));
var role_id = $(this).attr("id_role");
var action_id = $(this).attr("id_action");
var acces = $(this).is(':checked');
// alert(role_id);
// alert(action_id);
$.ajax({
type: "POST",
// url:'Privilege/ACL/addACL',
url: 'Detect/Acl/modifrole',
// data: {
// "id_role": role_id,
// "id_action": action_id,
// "droit": droit},
data: {
"id_role": role_id,
"id_action": action_id,
"acces": acces
},
Success: function (result) {
alert('Success');
console.log(result);
},
Error: function () {
alert('Error');
}})
});
});
this function in controller:
public function modifroleAction() {
$request = $this->getRequest();
// echo'<pre>'; print_r($this->getRequest());die;
if ($request->isPost()) {
$parametres = $this->params()->fromPost();
$acl = new Acl();
$acl->fk_role_id = $parametres['role_id'];
$acl->fk_action_id = $parametres['action_id'];
$acces = $parametres['acces'];
if ($acces == "false") {
$acl->acces = 0;
} else {
$acl->acces = 1;
}
$this->getAclTable()->saveAcl($acl);
return $this->redirect()->toRoute('acl');
}
}
Can you help me ?
You are trying to get data by $parametres['role_id'] and $parametres['action_id'] that means role_id and action_id
But you sending -
data: {
"id_role": role_id,
"id_action": action_id,
"acces": acces
},
that means id_role, and id_action.
Change your post index may work.

jquery how to refresh the table without refreshing the page?

i created a table with the help of kendoGrid data table plugin in which i perform a delete after the delete table sholud get reload and do not the show the deleted user but table doesnot reload and still showing the user in table when i refresh the page the user details will be gone i have tired the following code but it is not working
Note:delete operation is working properly
<head>
<script>
$(function () {
$("#example").dataTable();
})
</script>
<script>
$(document).ready(function () {
$("#example").kendoGrid({dataSource: {
pageSize: 10
},
editable: "popup",
sortable: true,
filterable: {
extra: false,
operators: {
string: {
contains: "Contains",
startswith: "Starts with"
}
}
},
pageable: true,
});
});
</script>
<script>
function deleteuser(obj) {
var uid = obj.id;
var uname = obj.name;
if (confirm("This user '" + uname + "' maybe using some other events, Are you sure to delete this user?")) {
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
//alert(xmlhttp.responseText.trim());
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//alert(xmlhttp.responseText.trim());
if (xmlhttp.responseText.trim() == 'deleted') {
alert('This user "' + uname + '" succesfully deleted');
$('#example').data('kendoGrid').dataSource.read();
} else
alert('Error : user cannot deleted');
}
}
var url = "deleteuser.php?id=" + uid;
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
}
</script>
</head>
<body>
<div>
<table id="example">
<thead>
<tr>
<td>Action</td>
<td>Name</td>
<td>Username</td>
<td>Email</td>
</tr>
</thead>
<tbody>
<?php
$sql = "SELECT * from registration";
$result = $conn->query($sql);
while ($row = $result->fetch_assoc()) {
?>
<tr>
<td><button class="btn btn-danger btn-xs" id="<?php echo $row['user_id'] ?>" onClick="deleteuser(this);" name="<?php echo $row['first_name'] ?>" title="Delete"><i class="fa fa-trash-o"></i></button></td>
<td><?php echo $row['first_name'] ?></td>
<td><?php echo $row['user_name'] ?></td>
<td><?php echo $row['email'] ?></td>
<?php
}
?>
</tr>
</tbody>
</table>
</div>
</body>
deleteuser.php
<?php
session_start();
$id = $_GET['id'];
include("../model/functions.php");
$table = "registration";
$condition = "user_id=" . $id . "";
$delete = Deletedata($table, $condition);
if ($delete === TRUE) {
echo'deleted';
} else {
echo 'not deleted';
}
?>
You are not be able to update the table data as is because you have not defined where the table gets the data. The can either refresh the entire page, or create a datasource with a transport & url that you can use to get the data.
When you populate the table server side:
<tbody>
<?php
$sql = "SELECT * from registration";
$result = $conn->query($sql);
while ($row = $result->fetch_assoc()) {
?>
<tr>
<td><button class="btn btn-danger btn-xs" id="<?php echo $row['user_id'] ?>" onClick="deleteuser(this);" name="<?php echo $row['first_name'] ?>" title="Delete"><i class="fa fa-trash-o"></i></button></td>
<td><?php echo $row['first_name'] ?></td>
<td><?php echo $row['user_name'] ?></td>
<td><?php echo $row['email'] ?></td>
<?php
}
?>
</tr>
</tbody>
There is nothing for the table to refresh.
You need to add a source of data for the table to get the data from.
Ordinarily, I define the datasource for the grid separate from the grid definition itself.
As an example:
var gridDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "someurl/to/my/data"
}
},
schema: {
model: { id: "user_id" }
}
});
Then you can define your table something like this:
var jgrid = $("#example").kendoGrid({
columns: [
{
field: "first_name",
title: "First Name"
},
{
field: "user_name",
title: "User Name",
},
{
field: "email",
title: "Email"
}
],
dataSource: gridDataSource
}).data("kendoGrid");
$('#GridName').data('kendoGrid').dataSource.read();
$('#GridName').data('kendoGrid').refresh();

PHP Mysql Table Pagination

Ive been try to make a page with Pagination on table. Upon button click, the table in main.php got populated by the first 16 rows retrieved from the query in page.php. For example the retrieved rows were 20. So there would be an excess of 4 for the second page. The thing is when I clicked the "Next" button to show the missing 4 records, the page is then diverted to page.php with the missing records. What I want to happen is for the 20 records in main.php be replaced by the 4 records.
MAIN.PHP
<div id="section">
<head3>Asset Assignment</head3><br><br>
<table>
<td>
<tr>Search Asset:</tr>
<tr><input type="text" id="sidt" name="sid"></tr>
<tr><input type="button" name="searchSub" value="Search" onClick="searchItem()"></tr>
</td>
</table><br>
<table>
<tr>
<td>Employee ID</td>
<td>Asset Serial Number</td>
</tr>
<tr>
<td><input type="text" name="empID"></td>
<td><input type="text" name="srlID"></td>
</tr>
<tr>
<td align="right"><input type="button" name="assign" value="Assign" onClick="assignItem()"></td>
</tr>
</table><br>
</div>
<div id="section2"></div>
JAVASCRIPT
function searchItem()
{
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
var data = "asid=" + document.getElementById("sidt").value;
xhr.open("POST", "page.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(data);
xhr.onreadystatechange = display_data;
function display_data()
{
if (xhr.readyState == 4)
{
if (xhr.status == 200)
{
document.getElementById("section2").innerHTML = xhr.responseText;
}
else
{
alert('There was a problem with the request.');
}
}
}
}
function assignItem(){}
PAGE.PHP
<?PHP
session_start();
$dbHost = "localhost";
$dbUser = "root";
$dbPass = "password";
$dbDatabase = "awsims";
$db = new PDO("mysql:dbname=$dbDatabase;host=$dbHost;port=3306", $dbUser, $dbPass);
if (!isset($_GET['startrow']) or !is_numeric($_GET['startrow'])) {
$startrow = 0;
} else {
$startrow = (int)$_GET['startrow'];
}
$sql = $db->prepare("SELECT * FROM assets LIMIT $startrow, 16");
$sql->execute();
$fetch = $sql->rowCount();
$num=$fetch;
if($num>0)
{
echo "<table style='width: 100%' border='1'>";
echo "<tr><td>ID</td><td>Drug</td><td>quantity</td></tr>";
for($i=0;$i<$num;$i++)
{
$row = $sql->fetch(PDO::FETCH_ASSOC);
$a = $row['SerialNumber'];
$b = $row['AssetType'];
$c = $row['AssetSubType'];
echo "<tr>";
echo "<td>$a</td>";
echo "<td>$b</td>";
echo "<td>$c</td>";
echo "</tr>";
}
echo "</table>";
}
echo '<a href='.$_SERVER['PHP_SELF'].'?startrow='.($startrow+16).'>Next</a>';
$prev = $startrow - 16;
//if ($prev >= 0)
echo '<a href='.$_SERVER['PHP_SELF'].'?startrow='.$prev.'>Previous</a>';
?>
Try changing your sql statement to as following query.
$sql = $db->prepare("SELECT * FROM assets LIMIT 16 OFFSET $startrow");
The next and previous link code should be like following.
echo '<a href='.$_SERVER['PHP_SELF'].'?startrow='.($startrow+1).'>Next</a>';
$prev = $startrow - 1;
echo '<a href='.$_SERVER['PHP_SELF'].'?startrow='.$prev.'>Previous</a>';
Here is the easiest and smartest PHP MySQL Pagination example I had ever read! Very well explained and a full code is provided which is tested and working 100%.

Categories

Resources