Cakephp 为什么AJAX请求会触发400响应,尽管使用安全组件解锁了操作?

Cakephp 为什么AJAX请求会触发400响应,尽管使用安全组件解锁了操作?,cakephp,cakephp-4.x,Cakephp,Cakephp 4.x,我试图让ajax请求在CakePHP4中工作,但继续运行到CSRF保护中 在我的控制器中: 公共函数beforeFilter(EventInterface$event) { 父级::beforeFilter($event); $this->Security->setConfig('unlockdactions',['players']); } 公共职能扮演者() { $players=['Sjaak Afhaak','Aad Kippezaad','Gras Kaffer','Tedje van

我试图让ajax请求在CakePHP4中工作,但继续运行到CSRF保护中

在我的控制器中:

公共函数beforeFilter(EventInterface$event)
{
父级::beforeFilter($event);
$this->Security->setConfig('unlockdactions',['players']);
}
公共职能扮演者()
{
$players=['Sjaak Afhaak','Aad Kippezaad','Gras Kaffer','Tedje van Es'];
如果($this->request->is('ajax')){
$this->response=$this->response->withDisabledCache();
}
$letter=trim($this->request->getData('letter'));
如果(!空($字母)){
$players=array\u filter($speler,function($haystack)use($letter){
返回(strpos($haystack,$letter));
});
}
$this->set(紧凑型('players');
$this->viewBuilder()->setOption('serialize',['players']);
$this->RequestHandler->renderAs($this,'json');
}
然后在模板文件中:


球员
...
$(文档).ready(函数(){
$(文档)。关于(“提交”、“表格”、功能(事件){
var$form=$(此);
var$target=$('div.response');
var csrf=$('input[name=_csrfToken],$form.val();
var data={letter:$('input[name=letter]',$form).val()};
$target.html(“”);
$.ajax({
方法:“张贴”,
url:$form.attr('action'),
发送前:函数(xhr){
setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhr.setRequestHeader('X-CSRF-Token',CSRF);
},
数据:数据,
数据类型:“json”
})
.完成(功能(响应){
var项目=[];
$。每个(响应、功能(键、val){
items.push(“
  • ”+val+“
  • ”); }); $(“
      ”{ “类”:“spelers列表”, html:items.join(“”) }).追加(目标美元); }); event.preventDefault(); }); });
    如果ajax调用中没有beforeSend,我将得到403响应。 如果我包括X-CSRF-Token,我将收到400响应

    2020-06-18 09:49:38 Error: [Cake\Http\Exception\BadRequestException] `_Token` was not found in request data. in src\vendor\cakephp\cakephp\src\Controller\Component\FormProtectionComponent.php on line 143
    Stack Trace:
    - src\vendor\cakephp\cakephp\src\Controller\Component\FormProtectionComponent.php:97
    - src\vendor\cakephp\cakephp\src\Event\EventManager.php:309
    - src\vendor\cakephp\cakephp\src\Event\EventManager.php:286
    - src\vendor\cakephp\cakephp\src\Event\EventDispatcherTrait.php:92
    - src\vendor\cakephp\cakephp\src\Controller\Controller.php:569
    - src\vendor\cakephp\cakephp\src\Controller\ControllerFactory.php:72
    - src\vendor\cakephp\cakephp\src\Http\BaseApplication.php:229
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:77
    - src\vendor\cakephp\cakephp\src\Http\Middleware\BodyParserMiddleware.php:164
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:73
    - src\vendor\cakephp\authorization\src\Middleware\AuthorizationMiddleware.php:129
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:73
    - src\vendor\cakephp\authentication\src\Middleware\AuthenticationMiddleware.php:124
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:73
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:77
    - src\vendor\cakephp\cakephp\src\Http\Middleware\CsrfProtectionMiddleware.php:138
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:73
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:58
    - src\vendor\cakephp\cakephp\src\Routing\Middleware\RoutingMiddleware.php:166
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:73
    - src\vendor\cakephp\cakephp\src\Routing\Middleware\AssetMiddleware.php:68
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:73
    - src\vendor\cakephp\cakephp\src\Error\Middleware\ErrorHandlerMiddleware.php:119
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:73
    - src\vendor\cakephp\debug_kit\src\Middleware\DebugKitMiddleware.php:60
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:73
    - src\vendor\cakephp\cakephp\src\Http\Runner.php:58
    - src\vendor\cakephp\cakephp\src\Http\Server.php:90
    - src\webroot\index.php:41
    

    不确定是否相关,但我正在使用身份验证插件。()

    从stacktrace中可以看出,错误源于,而不是安全组件,因此安全组件上的解锁操作不会起任何作用

    安全组件已被弃用(烹饪书似乎没有提到这一点),而表单保护组件是需要替换它的实用程序之一(其他是和)-您不应该同时使用这两个组件,请删除安全组件(我的意思是删除相关的
    loadComponent()
    调用),并相应地配置表单保护组件

    $this->FormProtection->setConfig('unlockdactions',['players']);
    

    这里的文档确实需要大修,不仅安全组件没有弃用通知,而且表单保护组件也没有列在组件部分。

    请清空应用程序的错误/调试日志,发出一个失败的请求,然后检查日志以确定到底发生了什么错误,并在问题中包含日志内容。添加了错误日志。FormProtectionComponent似乎抛出了一个BadRequestException。不知道为什么,因为我使用了
    $this->Security->setConfig('unlockdactions',['players'])在beforeFilter中?非常感谢,这就是解决方案!:-)