Я разрабатываю CakePHP с конечной точкой GraphQL, построенной на Webonyx GraphQL-PHP пакет. Проблема в том, что методы post и multipart возвращают 400 неверных запросов. Сначала я думал, что это из-за того, что запрос предполётной обработки был обработан, а последующие действия проигнорированы или возникла простая проблема cors, но после обширной отладки и модификации кода. Я определил, что они настроены правильно. я использую этот Плагин для управления предполетным запросом. Конфигурация по умолчанию позволяет все источники и проблемы сохраняются.
Метод действия, обрабатывающий запрос, выглядит так.
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 отсутствует в данных запроса, но я отключаю CSRF в своей функции beforeFilter следующим образом.
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow('index');
$this->eventManager()->off($this->Csrf);
}
С другой стороны, будет ли использование соединения debug_kit, упомянутого в первых трех строках, более подробным выводом?
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);
}
}
Других решений пока нет …