[英]Refresh CSRF Token on AjaxPOST Datatables: CodeIgniter
我正在尝试让数据表在我的网站上运行。 但是当我点击搜索,下一页,排序时,它无法正常工作。 这是因为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;
来使我的数据表工作$config['csrf_regenerate'] = TRUE;
假,但我不希望这样。 我的猜测是dataSrc
部分不起作用,但我不确定。
你可以在这里看到它。
任何帮助都非常感谢。 谢谢!
刷新AjaxPOST数据表上的CSRF令牌:CodeIgniter
上述陈述是自我解释的,具有明确的含义:
我们在制作AjaxPOST时必须刷新CSRF令牌
那么,我们如何在CodeIgniter中刷新CSRF令牌?什么是CodeIgniter中的平均刷新CSRF。
如果您的AJAX使用AjaxGET而不是AjaxPOST,则不会出现问题,因为CSRF仅适用于POST数据。
或者,您需要获取新的CSRF令牌和Hash并在AjaxPOST调用中返回它,然后更新html或javascript代码中的令牌和哈希设置。
或者,您可以使用config元素$ config ['csrf_exclude_uris'] = array();使特定URL免于CSRF 。
或者,您可以使用配置元素$ config ['csrf_expire'] = 300设置使CSRF令牌到期的长时间段; 。 这里定义了5分钟到期CSRF令牌,在到期时间(从第一个POST时间戳开始)之前,您可以使用在触发第一个POST时由CodeIgniter生成的旧CSRF令牌。 如果在5分钟内第一次POST后没有POST触发器,CodeIgniter将使CSRF令牌到期,之后您需要获取新的CSRF令牌。 听起来很复杂..没问题
假设您重新加载页面并且CodeIgniter将设置新的CSRF哈希,您可以使用它来发出AjaxPOST请求。 但是如果没有提出任何请求或重新加载页面,那么在5分钟之后,旧的CSRF将过期。 现在,如果再次调用AjaxPOST请求,则会收到500/403错误。 这意味着CodeIgniter会使旧的CSRF哈希到期,因为您在5分钟后使用旧的CSRF哈希发出请求,现在实际上不存在....清除:)
那么,在制作AjaxPOST时我们可以做些什么来获得新的CSRF令牌?
背后的逻辑是,在使用GET创建任何AjaxPOST之前获取新的CSRF哈希。 将它设置在DOM中的某个位置或附加到AjaxSetup中。
我是CodeIgniter的新手...... :(你有什么例子......?
(布尔玛!!为什么你再次打我的车......)是的! :)
这是View 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>
这是控制器:
<?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
谢谢Neeraj! 你的解决方案对我有用。
我在CodeIgniter中使用了以下代码来表示AJAX DataTable。 这是在从DataTable的AJAX调用中获取结果时触发CSRF Refresh方法。
$('#table').DataTable({
"ajax": {
"url": "<?php echo site_url(); ?>list",
"type": "POST",
"dataSrc": function ( json ) {
$(document).CsrfAjaxGet();
return json.data;
}
}
});
请在脚本标记的页面中添加此行。
$(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
});
如果它不起作用,请告诉我
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.