我正在尝试使数据表在我的网站中工作。但是当我点击搜索、下一页、排序时,它不起作用。这是因为没有重新生成 CSRF token 。
这是我的代码:
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 中看到它。
任何帮助都受到高度赞赏。谢谢!
最佳答案
上述声明是不言自明的,并具有明确的含义:
我们必须在发出任何 AjaxPOST 请求之前刷新我们的 CSRF token
假设您重新加载页面并且 CodeIgniter 设置了新 CSRF 哈希,您可以使用它来发出 AjaxPOST 请求。但是如果不发出任何请求或重新加载页面,则在 5 分钟内,旧的 CSRF 将过期。现在,如果您再次调用 AjaxPOST 请求,您的响应中会出现 500/403 错误。这意味着 CodeIgniter 使旧的 CSRF 哈希过期,因为您在 CSRF 过期时间(5 分钟)内没有再次发出任何请求,之后当您发送带有 OLD CSRF token 的 HTTP POST 请求时,实际上已经消失了....清除 :)
使用 CodeIgniter CSRF 安全 $config['csrf_protection'] =
真的;
背后的逻辑是,在使用 GET 进行任何 AjaxPOST 之前获取新的 CSRF 哈希。将其设置在 DOM 中的某个位置或附加到您的 AjaxSetup 中。
我是 CodeIgniter 的新手 .. :( 你有任何例子吗..?
( bool 玛!!为什么你又撞到我的车了......)是的,当然!!! :)
这里是查看 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 关于javascript - 刷新 AjaxPOST 数据表上的 CSRF token : CodeIgniter,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44733693/