进行CURL发布请求时CakePHP中的CSRF令牌

时间:2018-07-24 22:05:17

标签: php curl post cakephp csrf

我对CakePHP很陌生,并且一段时间以来我一直在试图弄清这个问题。

正在发生的事情如下:

我基本上是在尝试使用php POST CURL从不同的IP /域到Cake应用程序获取结果。但是,每次这样做,我都会在CakePHP应用程序日志“缺少CSRF令牌Cookie”中不断收到错误消息。

我在网上浏览了文档和各种帖子,但是我仍然不完全了解。

我希望这里的人可以给我更好的解释,该错误意味着什么。与php建立CURL连接时,如何传递CSRF令牌?更重要的是,如何获得Cake应用程序的CSRF令牌?

抱歉,这听起来像是一个愚蠢的问题,但我真的迷失了方向,不知道该去哪里。非常感谢您的帮助。

编辑1 我们正在尝试将数据添加到系统中,当我们执行GET请求时,没有问题,那就是运行良好。问题来自发出POST请求。

编辑2 我添加了我的AppController代码和执行所有功能的其他控制器。我想做的就是让POST正常工作,这样我就可以实现添加或编辑存储在数据库中的数据的功能。

AppController.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();
    }
  }
}

1 个答案:

答案 0 :(得分:0)

CSRF是一种机制,可通过生成令牌和一些隐藏字段来防止HTML表单被篡改。使用curl时,您将没有HTML表单,因此不会生成令牌,因此根本无法进行这种控制。您必须禁用该安全性。

一个简单的答案可能是:在appController.php中禁用CSRF安全性。

if (!$this->request->is('ajax')) {
    $this->loadComponent('Security');
    $this->loadComponent('Csrf');
}

您当然可以无条件地执行此操作,当然可以在其他每个控制器的initialize()函数中重新启用它。但是您不想这样做。

一种更好的解决方案是在特定控制器中的两个不同位置针对特定操作禁用特定控制器中的Security AND CSRF:

  1. https://book.cakephp.org/3.0/en/controllers/components/csrf.html#disabling-the-csrf-component-for-specific-actions
  2. 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);
}

Curl命令(在这里我发布了一个文件和一些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
    }
}