php - 执行 CURL Post 请求时 CakePHP 中的 CSRF 令牌
问题描述
我对 CakePHP 很陌生,我一直在尝试解决这个问题一段时间。
正在发生的事情如下:
我基本上是在尝试使用 php POST CURL 从不同的 IP/域到 Cake 应用程序获得结果。但是,每次我这样做时,我都会在 CakePHP 应用程序日志“Missing CSRF Token Cookie”中不断收到错误消息。
我已经浏览了在线文档和各种帖子,但我仍然不完全理解这一点。
我希望这里有人可以更好地解释这个错误的含义。与 php 建立 CURL 连接时如何传递 CSRF 令牌?更重要的是如何获得 Cake 应用程序 CSRF Token?
对不起,如果这听起来像一个愚蠢的问题,但我真的迷路了,不知道还能去哪里找。我提前感谢您的帮助。
编辑 1 我们正在尝试将数据添加到系统中,当我们执行 GET 请求时没有问题,该请求运行良好。问题来自执行 POST 请求。
编辑 2 我正在添加我的 AppController 代码和执行所有功能的其他控制器。我想要做的是让 POST 工作,所以我可以实现添加或编辑存储在数据库中的数据的功能。
应用控制器.php
namespace App\Controller;
use Cake\Controller\Controller;
use Cake\Event\Event;
class AppController extends Controller
{
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler', [
'enableBeforeRedirect' => false,
]);
$this->loadComponent('Flash');
}
}
WebservicesController.php
namespace App\Controller;
use Cake\Event\Event;
class WebservicesController extends AppController{
protected $responseBody = [];
public function beforeRender(Event $event){
foreach($this->responseBody as $responseKey=>$response){
$this->set($responseKey, $response);
}
$this->set('_serialize', array_keys($this->responseBody));
}
public function initialize(){
parent::initialize();
$this->RequestHandler->renderAs($this, 'json');
}
public function index(){
///getting data
$this->request->allowMethod(['get']);
$id = $this->request->getQuery("id");
$this->responseBody["statusCode"] = 200;
$this->responseBody['statusDescription'] = "";
$this->responseBody['data'] = array();
}
public function getOneItem(){
$this->request->allowMethod(['post']);
if ($this->request->is('post')) {
//Add/Edit Data in here.
$id = $this->request->getQuery("id");
$this->responseBody["statusCode"] = 200;
$this->responseBody['statusDescription'] = "";
$this->responseBody['data'] = array();
}
}
}
解决方案
CSRF 是一种通过生成令牌和一些隐藏字段来防止 HTML 表单篡改的机制。使用 curl,您没有 HTML 表单,因此不会生成令牌,因此这种控制是不可能的。您必须禁用该安全性。
一个简单的答案可能是:在 appController.php 中禁用 CSRF 安全性。
if (!$this->request->is('ajax')) {
$this->loadComponent('Security');
$this->loadComponent('Csrf');
}
当然,您可以无条件地执行此操作,并在每个其他控制器中的 initialize() 函数中重新启用它。但你不会想要那样做。
一种更好的解决方案是在特定控制器中禁用 Security AND CSRF 以执行特定操作,如文档中所述,在两个不同的位置:
- https://book.cakephp.org/3.0/en/controllers/components/csrf.html#disabling-the-csrf-component-for-specific-actions
- https://book.cakephp.org/3.0/en/controllers/components/security.html#disabling-security-component-for-specific-actions
在我的情况(和你的情况)中,我想通过 POST 和 curl 添加一些东西。
所以控制器中的这些行有效:
public function beforeFilter(Event $event)
{
$this->Security->setConfig('unlockedActions', ['add']);
$this->getEventManager()->off($this->Csrf);
}
卷曲命令(在这里我发布一个文件和一些 id,但这可能是任何东西):
curl -k -X POST --cookie CAKEPHP=xxxx -F "file=@index.jpeg" -F fk_id=1 https://hostname/cake/files.json
结果是对象的 json 表示。
{
"file": {
"fk_id": 1,
"file": {
"tmp_name": "\/tmp\/phpBUaHon",
"error": 0,
"name": "index.jpeg",
"type": "image\/jpeg",
"size": 7861
},
"created": "2018-08-22T06:08:06+00:00",
"modified": "2018-08-22T06:08:06+00:00",
"id": 14
}
}
推荐阅读
- elasticsearch - 在子字段中进行排除(不得)搜索
- python - 如何检查一列中的值是否可以包含多于另一列中的值
- python - 多列的高效搜索
- python - 在 SymPy 中有没有一种在球坐标中工作的方法?
- c++ - 如何使用 WriteConsoleOutput 编写 UNICODE 或扩展 ASCII
- sorting - 如何使用 JCL 用另一行覆盖一行
- json - JSON 文件中的 SwiftUI 搜索列表
- spring - java.lang.NoClassDefFoundError: com/mysema/query/types/Predicate
- haskell - 如何编写一个函数,用给定的自定义字符替换每个输入字符串的第一个字符?
- javascript - FFmpeg 通过 UDP 和 DataChannel 到 WebRTC 以实现低延迟屏幕共享