CakePHP 3.5 400错误请求

时间:2018-01-29 01:59:30

标签: php cakephp cors graphql preflight

我正在使用基于webonyx GraphQL-PHP包构建的GraphQL端点开发CakePHP。问题是post和multipart方法返回400个错误请求。我最初认为这是由于预检请求得到处理和后续忽略或简单的cors问题,但经过大量调试和修改后的代码。我确定这些设置正确。我使用this插件来管理预检请求。默认配置允许所有来源和问题持续存在。

处理请求的操作方法如下所示。

    public function index(){
        $this->autoRender = false;

        $data = $this->request->input('json_decode');

        if(!$data) {
            $data = $this->request->getParam('?');
        }

        if(!$data) $data = [];
        $data += ['query' => null, 'variables' => null];
        $result = $this->GraphQL->query($data);

        $this->response = $this->response
        ->withHeader('Access-Control-Allow-Origin', '*')
        ->withHeader('Access-Control-Allow-Methods', ['GET', 'POST', 'OPTIONS'])
        ->withHeader('Access-Control-Allow-Credentials', 'true')
        ->withHeader('Access-Control-Max-Age','8600')
        ->withType('application/json')
        ->withStringBody(json_encode($result));
        return $this->response;
    }

但那不是问题的原因。 POST和MULTIPART甚至不会在返回错误之前进入此功能。我一直用GraphiQL Feen测试端点。

这是错误日志中的结果堆栈跟踪。

2018-01-29 22:28:35 Warning: DebugKit not enabled. You need to either install pdo_sqlite, or define the "debug_kit" connection name.
2018-01-29 22:28:36 Warning: DebugKit not enabled. You need to either install pdo_sqlite, or define the "debug_kit" connection name.
2018-01-29 22:28:47 Warning: DebugKit not enabled. You need to either install pdo_sqlite, or define the "debug_kit" connection name.
2018-01-29 22:28:48 Error: [Cake\Controller\Exception\AuthSecurityException] '_Token' was not found in request data.
Request URL: /api
Stack Trace:
#0 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Controller/Component/SecurityComponent.php(316): Cake\Controller\Component\SecurityComponent->_validToken(Object(App\Controller\ApiController))
#1 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Controller/Component/SecurityComponent.php(121): Cake\Controller\Component\SecurityComponent->_validatePost(Object(App\Controller\ApiController))
#2 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Event/EventManager.php(416): Cake\Controller\Component\SecurityComponent->startup(Object(Cake\Event\Event))
#3 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Event/EventManager.php(393): Cake\Event\EventManager->_callListener(Array, Object(Cake\Event\Event))
#4 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Event/EventDispatcherTrait.php(110): Cake\Event\EventManager->dispatch(Object(Cake\Event\Event))
#5 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Controller/Controller.php(506): Cake\Controller\Controller->dispatchEvent('Controller.star...')
#6 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Http/ActionDispatcher.php(114): Cake\Controller\Controller->startupProcess()
#7 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Http/ActionDispatcher.php(93): Cake\Http\ActionDispatcher->_invoke(Object(App\Controller\ApiController))
#8 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Http/BaseApplication.php(108): Cake\Http\ActionDispatcher->dispatch(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response))
#9 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Http/Runner.php(65): Cake\Http\BaseApplication->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner))
#10 /path/radioactive-cake/app/vendor/ozee31/cakephp-cors/src/Routing/Middleware/CorsMiddleware.php(31): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response))
#11 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Http/Runner.php(65): Cors\Routing\Middleware\CorsMiddleware->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner))
#12 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php(104): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response))
#13 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Http/Runner.php(65): Cake\Routing\Middleware\RoutingMiddleware->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner))
#14 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Routing/Middleware/AssetMiddleware.php(88): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response))
#15 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Http/Runner.php(65): Cake\Routing\Middleware\AssetMiddleware->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner))
#16 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php(95): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response))
#17 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Http/Runner.php(65): Cake\Error\Middleware\ErrorHandlerMiddleware->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner))
#18 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Http/Runner.php(51): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response))
#19 /path/radioactive-cake/app/vendor/cakephp/cakephp/src/Http/Server.php(81): Cake\Http\Runner->run(Object(Cake\Http\MiddlewareQueue), Object(Cake\Http\ServerRequest), Object(Cake\Http\Response))
#20 /path/radioactive-cake/app/webroot/index.php(40): Cake\Http\Server->run()
#21 {main} 

它还说明请求数据中缺少_Token但是我在我的beforeFilter函数中禁用了CSRF。

public function beforeFilter(Event $event)
{
    parent::beforeFilter($event);
    $this->Auth->allow('index');
    $this->eventManager()->off($this->Csrf);
}

在旁注中会使用前三行中提到的debug_kit连接提供更详细的输出吗?

1 个答案:

答案 0 :(得分:0)

CSRF未正确禁用。我的beforeFilter应该是这样的。

public function beforeFilter(Event $event)
{
    parent::beforeFilter($event);
    $this->Auth->allow('index');
    $actions = [
        'index',
    ];

    if (in_array($this->request->params['action'], $actions)) {
        // for csrf
        $this->eventManager()->off($this->Csrf);

        // this is a must have
        $this->Security->config('unlockedActions', $actions);
    }
}