我试图让数据表在我的网站上运行。但是当我点击搜索,下一页,排序时,它无法正常工作。这是因为CSRF令牌没有被重新生成。
这是我的代码:
HTML
<input type="hidden" id="hash" name="csrf_test_name" value="802daa2efaf69edb83b571d7bf7510aa">
<table id="test-table" class="table table-hover">
<thead>
<tr>
<th>No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Phone</th>
<th>Address</th>
<th>City</th>
<th>Country</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<th>No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Phone</th>
<th>Address</th>
<th>City</th>
<th>Country</th>
</tr>
</tfoot>
</table>
JS
<script type="text/javascript">
var table;
$(document).ready(function() {
//datatables
table = $('#test-table').DataTable({
"processing": true, //Feature control the processing indicator.
"serverSide": true, //Feature control DataTables' server-side processing mode.
"order": [], //Initial no order.
"ajax": {
"url": "http://oss-dev.forexworld.us/oss/user/ajax_receiving",
"type": "POST",
data: {
'csrf_test_name' : '802daa2efaf69edb83b571d7bf7510aa'
},
dataSrc: function ( json ) {
if(json.csrf_test_name !== undefined) $('meta[name=csrf_test_name]').attr("content", json.csrf_token);
return json.data;
}
},
"columnDefs": [
{
"targets": [ 0 ], //first column / numbering column
"orderable": false, //set not orderable
},
],
});
});
</script>
我可以通过将$config['csrf_regenerate'] = TRUE;
设置为 FALSE 来使我的数据表工作,但我不想这样做。我的猜测是dataSrc
部分不起作用,但我不确定。
您可以在行动中看到它 here 。
非常感谢任何帮助。谢谢!
答案 0 :(得分:3)
刷新AjaxPOST数据表上的CSRF令牌:CodeIgniter
以上陈述是自我解释的&amp;有明确的含义:
我们在制作AjaxPOST时需要刷新CSRF令牌
那么,我们如何在CodeIgniter&amp;中刷新CSRF令牌?什么是CodeIgniter中的平均刷新CSRF。
如果您的AJAX使用AjaxGET而不是AjaxPOST,则不会出现问题,因为CSRF仅适用于POST数据。
或者,您需要获取新的CSRF令牌和Hash并在AjaxPOST调用中返回它,然后更新令牌和哈希 您的html或javascript代码中的设置。
或者,您可以使用配置元素 $ config ['csrf_exclude_uris'] = array();
使该特定网址免于CSRF
或者,您可以使用配置元素 $ config ['csrf_expire'] = 300; 设置使CSRF令牌过期的较长时间段。这里定义了5分钟到期CSRF令牌,在到期时间(从第一个POST时间戳开始)之前,您可以使用在触发第一个POST时由CodeIgniter生成的旧CSRF令牌。如果在5分钟内第一次POST后没有POST触发器,CodeIgniter将使CSRF令牌到期,之后您需要获取新的CSRF令牌。听起来很复杂..没问题
假设您重新加载页面&amp; CodeIgniter将设置新的CSRF哈希,您可以使用它来发出AjaxPOST请求。但是如果没有提出任何请求或重新加载页面,那么在5分钟之后,旧的CSRF将过期。现在,如果再次调用AjaxPOST请求,则会收到500/403错误。这意味着CodeIgniter会使旧的CSRF哈希失效,因为您在5分钟后使用旧的CSRF哈希发出请求,现在实际上不存在....清除:)
那么,在制作AjaxPOST时我们可以做些什么来获取新的CSRF令牌?
背后的逻辑是,在使用GET创建任何AjaxPOST之前获取新的CSRF哈希。将它设置在DOM中的某个位置或附加在AjaxSetup中。
我是CodeIgniter的新手...... :(你有什么例子吗?
(布尔玛!!为什么你再次打我的车......)是的! :)
以下是查看Html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="<?=$this->security->get_csrf_token_name()?>" content="<?=$this->security->get_csrf_hash()?>"/>
<title>CodeIgniter CSRF Refresh Demo</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
// Set CodeIgniter base_url in JavaScript var to use within
var _BASE_URL_ = "<?=base_url()?>";
var _CSRF_NAME_ = "<?=$this->security->get_csrf_token_name()?>";
(function($) {
/**
* New jQuery function to set/refresh CSRF token in Body & to attach AjaxPOST
* @param {[type]} $ [description]
* @return {[type]} [description]
*/
$.fn.CsrfAjaxSet = function(CsrfObject) {
// getting meta object from body head section by csrf name
var CsrfMetaObj = $('meta[name="' + _CSRF_NAME_ + '"]'),
CsrfSecret = {};
// if CsrfObject not set/pass in function
if (typeof CsrfObject == 'undefined') {
// assign meta object in CsrfObject
CsrfObject = CsrfMetaObj;
// get meta tag name & value
CsrfSecret[CsrfObject.attr('name')] = CsrfObject.attr('content');
}
// CsrfObject pass in function
else {
// get Csrf Token Name from JSON
var CsrfName = Object.keys(CsrfObject);
// set csrf token name & hash value in object
CsrfSecret[CsrfName[0]] = CsrfObject[CsrfName[0]];
}
// attach CSRF object for each AjaxPOST automatically
$.ajaxSetup({
data: CsrfSecret
});
};
/**
* New jQuery function to get/refresh CSRF token from CodeIgniter
* @param {[type]} $ [description]
* @return {[type]} [description]
*/
$.fn.CsrfAjaxGet = function() {
return $.get(_BASE_URL_ + 'Csrfdata', function(CsrfJSON) {
$(document).CsrfAjaxSet(CsrfJSON);
}, 'JSON');
};
})(jQuery);
// On DOM ready attach CSRF within AjaxPOST
$(document).CsrfAjaxSet();
</script>
</head>
<body>
<button class="button">Click Me to Trigger AjaxPOST</button>
<script type="text/javascript">
// on DOM ready
$(document).ready(function(){
// my button
$btn = $('.button');
// on button click
$btn.on('click', function(e){
// stop default event
e.preventDefault();
// trigger refresh csrf token
var CSRF = $(document).CsrfAjaxGet();
// use callback to put your AjaxPOST & Done!
CSRF.success(function(){
$.ajax({
url: _BASE_URL_ + 'Controller/Method',
method: 'POST',
success: function(data){
alert('Success');
},
error: function(xhr, status, error){
alert(error);
}
});
});
});
});
</script>
</body>
</html>
以下是Controller:
<?php
(defined('BASEPATH') or exit('No direct script access allowed'));
/**
* Class Csrfdata to return fresh CSRF hash value
*/
class Csrfdata extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
/**
* Return CodeIgniter CSRF name & Hash on request
* @return [type] [description]
*/
public function index()
{
if ($this->input->get()) {
$csrf = array();
$csrf_name = $this->security->get_csrf_token_name();
$csrf_hash = $this->security->get_csrf_hash();
$csrf[$csrf_name] = $csrf_hash;
echo json_encode($csrf);
}
}
}
/* End of file Csrfdata.php */
/* Location: ./application/controllers/Csrfdata.php */
希望大家都会喜欢这个答案,任何建议,评论都非常感谢...一如既往......:D
答案 1 :(得分:2)
谢谢Neeraj!你的解决方案对我有用。
我在CodeIgniter中使用了以下代码用于AJAX DataTable。这是在从DataTable的AJAX调用中获取结果时触发CSRF Refresh方法。
secondary
答案 2 :(得分:0)
请在页面的脚本标记中添加此行。
$(function($) {
// this script needs to be loaded on every page where an ajax POST
$.ajaxSetup({
data: {
'<?php echo $this->security->get_csrf_token_name(); ?>' : '<?php echo $this->security->get_csrf_hash(); ?>'
}
});
// now write your ajax script
});
如果不起作用,请告诉我