I am using CakePHP 5.0.5 to write an App that connect to Strava and get running activities for users.
Strava require a webhook so that it can push update event of user activity to my app. That is why I have to disable CSRF for that webhook action.
My webhook action is:
public function webhook()
{
// Event call back
if ($this->request->is('post')) {
$object_type = $this->request->getQuery('object_type');
if (!is_null($object_type)){
//do something later
}
$this->set('result', 'OK');
$this->viewBuilder()->setOption('serialize', ['result']);
return;
}
// Webhook subscription validation
if ($this->request->is('get')) {
$subcribe_result = $this->request->getQuery('hub_challenge');
if (!is_null($subcribe_result)){
$this->set('hub.challenge', $subcribe_result);
$this->viewBuilder()->setOption('serialize', ['hub.challenge']);
return;
}
}
}
I also disable CSRF for that webhook action like this:
public function initialize(): void
{
parent::initialize();
//$this->loadComponent('RequestHandler');
$this->Authentication->allowUnauthenticated(['webhook', 'webhook.json']);
$this->loadComponent('Csrf');
}
public function beforeFilter(\Cake\Event\EventInterface $event)
{
parent::beforeFilter($event);
// Check if the current action is the one for which you want to disable CSRF protection
if (($this->getRequest()->getParam('action') === 'webhook.json') || ($this->getRequest()->getParam('action') === 'webhook')) {
$this->getEventManager()->off($this->Csrf);
}
}
I also read Documentation for CakePHP 5, only find solution to disable CSRF for all actions which has prefix of something (“API”) in example below:
$csrf = new CsrfProtectionMiddleware();
// Token check will be skipped when callback returns `true`.
$csrf->skipCheckCallback(function ($request) {
// Skip token check for API URLs.
if ($request->getParam('prefix') === 'Api') {
return true;
}
});
How do I disable CSRF for only 1 specific action of a specific controller ?