我遇到了CodeIgniter/CSRF/JSON的问题。
我正在向PHP后端发送内容类型为“application/json”的http POST请求。有效负载是json数据。我将与数据一起传递生成并存储在CSRF cookie中的CSRF令牌。对于标准POST表单请求,它工作正常,但作为json发送时失败。
由于$\u POST数组因JSON内容类型而为空,CodeIgniter无法验证cookie并抛出错误。
如何让CodeIgniter检查JSON负载并验证我的CSRF令牌?
如果需要重写,最好扩展安全库,而不是直接编辑核心文件。
创建文件My_Security。在application/core/中使用php,并添加以下内容(来自上面的解决方案):
<?php
class My_Security extends CI_Security {
/**
* Verify Cross Site Request Forgery Protection
*
* @return object
*/
public function csrf_verify()
{
// If it's not a POST request we will set the CSRF cookie
if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST')
{
return $this->csrf_set_cookie();
}
// Do the tokens exist in both the _POST and _COOKIE arrays?
if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name])) {
// No token found in $_POST - checking JSON data
$input_data = json_decode(trim(file_get_contents('php://input')), true);
if ((!$input_data || !isset($input_data[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name])))
$this->csrf_show_error(); // Nothing found
else {
// Do the tokens match?
if ($input_data[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name])
$this->csrf_show_error();
}
}
else {
// Do the tokens match?
if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name])
$this->csrf_show_error();
} // We kill this since we're done and we don't want to
// polute the _POST array
unset($_POST[$this->_csrf_token_name]);
// Nothing should last forever
unset($_COOKIE[$this->_csrf_cookie_name]);
$this->_csrf_set_hash();
$this->csrf_set_cookie();
log_message('debug', 'CSRF token verified');
return $this;
}
}
为了解决这个问题,我必须更改位于“system/core/”中的“Security.php”文件的代码。
在功能“csrf_验证”中,替换该代码:
// Do the tokens exist in both the _POST and _COOKIE arrays?
if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]))
{
$this->csrf_show_error();
}
// Do the tokens match?
if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name])
{
$this->csrf_show_error();
}
通过那个代码:
// Do the tokens exist in both the _POST and _COOKIE arrays?
if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name])) {
// No token found in $_POST - checking JSON data
$input_data = json_decode(trim(file_get_contents('php://input')), true);
if ((!$input_data || !isset($input_data[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name])))
$this->csrf_show_error(); // Nothing found
else {
// Do the tokens match?
if ($input_data[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name])
$this->csrf_show_error();
}
}
else {
// Do the tokens match?
if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name])
$this->csrf_show_error();
}
该代码首先检查$\u POST,然后如果未找到任何内容,则检查JSON负载。
实现这一点的理想方法是检查传入的请求内容类型头值。但令人惊讶的是,这样做并不直接。。。
如果有人有更好的解决方案,请张贴在这里。
干杯
或者,您可以通过在application/config/config上添加以下代码来跳过CSRF检查。第351行下方的php(基于CI 2.1.4)。
$config['csrf_expire'] = 7200; // This is line no. 351
/* If the REQUEST_URI has method is POST and requesting the API url,
then skip CSRF check, otherwise don't do. */
if (isset($_SERVER["REQUEST_URI"]) &&
(isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'POST') ))
{
if (stripos($_SERVER["REQUEST_URI"],'/api/') === false ) { // Verify if POST Request is not for API
$config['csrf_protection'] = TRUE;
}
else {
$config['csrf_protection'] = FALSE;
}
} else {
$config['csrf_protection'] = TRUE;
}
问题内容: 如何用Java发出HTTP Json请求?有图书馆吗?在“ HTTP Json请求”下,我的意思是使用Json对象作为数据进行POST,并以Json接收结果。 问题答案: 除了本身进行HTTP请求(甚至可以仅使用 **java.net.URL.openConnection** 即可完成)之外,您还需要一个JSON库。为了方便地与POJO绑定,我建议使用Jackson。 因此,类似: (
问题内容: 进行Ajax调用时,将contentType设置为application / json而不是默认的x-www-form- urlencoded时,服务器端(在PHP中)无法获取post参数。 在以下工作示例中,如果我在ajax请求中将contentType设置为“ application / json”,则PHP $ _POST将为空。为什么会这样?如何在PHP中正确处理content
概述 我将使用API网关作为基于Spring Security性的身份验证。我刚刚按照https://spring.io/guides/tutorials/spring-security-and-angular-js/链接中的步骤创建了一个基于其对应的github项目的“对双”模块的项目https://github.com/spring-guides/tut-spring-security-and
问题内容: 我想仅使用本机Python库将JSON编码的数据发送到服务器。我喜欢请求,但我根本无法使用它,因为我无法在运行脚本的计算机上使用它。我需要没有它。 我的服务器是本地WAMP服务器。我总是得到一个 urllib.error.HTTPError:HTTP错误500:内部服务器错误 我 100%确信 这 不是 服务器问题,因为在同一台计算机上,同一台服务器上的同一数据,相同的url与请求库和
问题内容: 我已经在Java中生成了一个包含JSON对象的HTMLPost请求,并希望在PHP中对其进行解析。 并在服务器上 我猜这是因为JSON特殊字符已编码。 json_decode返回空响应 知道为什么吗? 问题答案: 实际上,您不是在发布实体,而是在发布具有单个值对json =(encoded json)的HTTP表单实体()。 代替 尝试