49

Is there a way to disable CSRF validation for some actions of the controller keeping it enabled for the other ones?

In my case I have several configurable Action classes, that are intended to be injected into controllers. I can't pass csrf validation token into the AJAX request because the thing I'm working with is external (made not by me) WYSIWYG plugin at the frontend. Yes, I can still disable csrf validation of the whole controller using these actions, but it may be insecure.

arogachev
  • 33,150
  • 7
  • 114
  • 117
coderlex
  • 602
  • 1
  • 5
  • 9

4 Answers4

105

For the specific controller / actions you can disable CSRF validation like so:

use Yii;

...

Yii::$app->controller->enableCsrfValidation = false;

Or inside a controller:

$this->enableCsrfValidation = false;

Take a look at $enableCsrfValidation property of yii\web\Controller.

Update:

Here is some specification.

If you want to disable CSRF validation for individual action(s) you need to do it in beforeAction event handler because CSRF token is checked before action runs (in beforeAction of yii\web\Controller).

/**
 * @inheritdoc
 */
public function beforeAction($action)
{            
    if ($action->id == 'my-method') {
        $this->enableCsrfValidation = false;
    }

    return parent::beforeAction($action);
}

Official docs:

arogachev
  • 33,150
  • 7
  • 114
  • 117
  • 2
    Checking of this parameter is processing in beforeAction, so it would be useless to do this inside of action. – yujin1st May 04 '15 at 05:05
  • @yujin1st I actually didn't mention anything about where exactly to place it, but yes, it's needed to be placed in `beforeAction`. Thanks for remark, updated the answer. – arogachev May 28 '15 at 09:28
  • but I had used your code exactly as you had it replacing with the action – Michael St Clair Jul 02 '15 at 17:53
  • The `$action` should already contain action id, try to `var_dump` it inside the method, what's the result? – arogachev Jul 02 '15 at 17:55
  • it gave me an array where the action id I was look for was `$action['id']`, but when I tried to use that it gave me some error saying I couldn't use `$action` as an array. – Michael St Clair Jul 02 '15 at 17:58
  • Please edit $action == 'my-method' on $action->id == 'my-method' – Alex Oct 13 '15 at 07:33
  • 1
    @Alex Thanks for remark, corrected the answer. By the way, you can suggest edit too. – arogachev Oct 13 '15 at 08:06
9

For me this is what worked

public function beforeAction($action) {
    if($action->id == 'my-action') {
        Yii::$app->request->enableCsrfValidation = false;
    }
    return parent::beforeAction($action);
}
6

Put this inside your controller, just replace index with whatever action you want to disable csrf on.

public function beforeAction()
{      
    if ($this->action->id == 'index') {
        $this->enableCsrfValidation = false;
    }
    return true;
}
Muhammad Omer Aslam
  • 22,976
  • 9
  • 42
  • 68
Michael St Clair
  • 5,937
  • 10
  • 49
  • 75
3

i have tried this and it worked .

Go to the specific controller and write this at the top.

public $enableCsrfValidation = false;
Shuhad zaman
  • 3,156
  • 32
  • 32
  • This disables CSRF validation for ALL actions in the controller. OP asked about individual actions. – Sarke May 25 '21 at 08:03