I have a project in Cakephp 3.6 in which 3 actions in MessageController are called by Ajax. I have a problem, however, when I send a request to one of the action, XHR returns to me this:
{
"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
}
This is one of the action what I try to call from 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);
}
}
And this is my 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");
}
}
});
});
I have read the documentation about Cross Site Request Forgery, and I tried to turn off the Csrf for these action first with:
public function beforeFilter(Event $event)
{
$this->getEventManager()->off($this->Csrf);
}
and then with:
public function beforeFilter(Event $event)
{
$this->Security->setConfig('unlockedActions', ['index', 'changepriority']);
}
But nothing. The Xhr return always the CSRF token mismatch. What can I do ?
Edit:
I change the action in this way:
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;
}
}
In that way the action works. Can it be like that?
$(...).val()
with the<?= json_encode(...); ?>
example. – ndm