我在Cakephp 3.6中有一个项目,其中Ajax调用了MessageController中的3个动作。但是,我有一个问题,当我向其中一个动作发送请求时,XHR会向我返回此信息:
{
"message": "CSRF token mismatch.",
"url": "\/messages\/changepriority\/8",
"code": 403,
"file": "D:\\xampp\\htdocs\\myapp\\vendor\\cakephp\\cakephp\\src\\Http\\Middleware\\CsrfProtectionMiddleware.php",
"line": 195
}
这是我尝试从Ajax调用的动作之一:
public function changepriority($id=null)
{
$this->autoRender = false;
$message = $this->Messages->get($id);
$message->priority = ($message->priority === false) ? true : false;
if ($this->Messages->save($message)) {
echo json_encode($message);
}
}
这是我的ajax:
$(".email-star").click(function(){
var idmessage = this.id;
$.ajax({
headers : {
'X-CSRF-Token': $('[name="_csrfToken"]').val()
},
dataType: "json",
type: "POST",
evalScripts: true,
async:true,
url: '<?php echo Router::url(array('controller'=>'Messages','action'=>'changepriority'));?>' +'/'+idmessage,
success: function(data){
if(data['priority'] === false) {
$("#imp_" + idmessage).removeClass("fas").removeClass('full-star').addClass( "far" );
}
else {
$("#imp_" + idmessage).removeClass("far").addClass( "fas" ).addClass("full-star");
}
}
});
});
我已经阅读了有关“跨站点请求伪造”的文档,并且尝试通过以下方法首先关闭Csrf:
public function beforeFilter(Event $event)
{
$this->getEventManager()->off($this->Csrf);
}
,然后加上:
public function beforeFilter(Event $event)
{
$this->Security->setConfig('unlockedActions', ['index', 'changepriority']);
}
但是什么都没有。 Xhr返回总是CSRF令牌不匹配。 我该怎么办?
编辑:
我以这种方式更改操作:
public function changepriority($id=null)
{
$this->autoRender = false;
$message = $this->Messages->get($id);
$message->priority = ($message->priority === false) ? true : false;
if ($this->Messages->save($message)) {
$content = json_encode($message);
$this->response->getBody()->write($content);
$this->response = $this->response->withType('json');
return $this->response;
}
}
以这种方式起作用。会是这样吗?
答案 0 :(得分:1)
首先检查您的$('[name="_csrfToken"]').val()
输出。
如果未获得任何输出,则需要检查csrfToken
隐藏字段是否存在。只需右键单击页面,然后单击View Page Source
如果不存在,则在创建Form时不会遵循正确的方法。基本上,使用Cake\View\Helper\FormHelper
创建表单时,将添加一个包含CSRF令牌的隐藏字段。
如果一切正确,请在header
beforeSend: function (xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('[name="_csrfToken"]').val());
},
Ps。 CakePHP不建议禁用CSRF,大多数开发人员都知道这一点。希望对您有所帮助。