I have a standalone action.
It is designed to work with csrf validation disabled to avoid error 400 "Unable to verify your data submission." As it is standalone I supposed to disable csrf validation in Action::beforeRun() method, as:
protected function beforeRun() {
\Yii::$app->controller->enableCsrfValidation = false;
return true;
}
But it takes no effect and seems the only way to do this is to use Controller::beforeAction(), but it wisely to have an ability to manage csrf validation in Action::beforeRun() for my opinion, since it is called "standalone" action.
Are you sure? It works well for me:
class TestAction extends Action
{
protected function beforeRun()
{
$this->controller->enableCsrfValidation = false;
return parent::beforeRun();
}
public function run()
{
var_dump(\Yii::$app->controller->enableCsrfValidation);
return '123';
}
}
Perhaps I have expressed my idea wrong, and you misunderstood me.
You are right, enableCsrfValidation is false indeed, but I expect that in this case CSRF token won't be validated, instead I get error 400 "Unable to verify your data submission.". It seems that Yii::$app->getRequest()->validateCsrfToken() is executed BEFORE enableCsrfValidation value is changed to false in Action::beforeRun()
Ah. Yes.
Currently it's calling module's beforeAction then controller's beforeAction where CSRF token is validated then it calls beforeRun of the action itself.
I doubt it could be changed in 2.0.x because of backwards compatibility reasons.
will this get changed? or will we add another event/method?
We want to verify token once so the question is about where to do it. I'm OK moving validation to after beforeRun() is called.
I'm not sure if we need to change anything. For standalone action it's possible to set enableClientValidation to false earlier, in init() method:
public function init()
{
parent::init();
\Yii::$app->controller->enableCsrfValidation = false;
}
This code will run before beforeAction() of yii\base\Controller and yii\web\Controller.
Also it won't affect other actions, init() runs only if this particular standalone action is requested.
If needed, I can add this to the docs somewhere.
@arogachev yes, that would be good.
Most helpful comment
I'm not sure if we need to change anything. For standalone action it's possible to set
enableClientValidationtofalseearlier, ininit()method:This code will run before
beforeAction()ofyii\base\Controllerandyii\web\Controller.Also it won't affect other actions,
init()runs only if this particular standalone action is requested.If needed, I can add this to the docs somewhere.