在 AjaxPOST 数据表上刷新 CSRF 令牌:CodeIgniter
上述陈述是不言自明的,并且具有明确的含义:
我们必须在发出任何 AjaxPOST 请求之前刷新我们的 CSRF 令牌
那么,我们将如何在 CodeIgniter 中刷新 CSRF Token & 在 CodeIgniter 中刷新 CSRF 是什么意思。
CSRF 令牌仅在您发出 POST 请求(ajax 帖子或基于普通表单的帖子)时才需要
另外,在发出任何 AjaxPOST 请求之前,您需要拥有新的 CSRF 令牌和哈希值。完成 Ajax 调用后,您必须更新 html 中的令牌和哈希值设置,或在 javascript 代码中另存为变量。
或者,您可以从 CSRF 中排除所需的 url(您可以告诉 CodeIgniter “亲爱的 CodeIgniter 听,当我将使用此 url 时,您不允许检查 CSRF 令牌并且从未要求我附加/发送 CSRF请求中的令牌。明白吗?是大师)使用配置元素 $config['csrf_exclude_uris'] = array('controller/method', '...');
或者,您可以使用配置元素 $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 哈希,因为您在 CSRF 过期时间(5 分钟)期间没有再次发出任何请求,之后当您发送带有 OLD CSRF 令牌的 HTTP POST 请求时,实际上已经消失了......清除:)
那么,在制作 AjaxPOST 时,我们可以做些什么来获取新的 CSRF 令牌..?
- 好吧,对于 GET 请求,您不需要发送任何 CSRF 令牌。
- 但是对于 POST 是的!如果你是,你必须在 AjaxPOST 中发送 CSRF
使用 CodeIgniter CSRF 安全 $config['csrf_protection'] =
是的;
背后的逻辑是,在使用 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>
这是控制器:
<?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 */
希望您喜欢答案和任何建议,非常感谢 cmets...一如既往.. :D