First, analyze the cause:
When you open csrf in the configuration file:
'Request' => array (
'Enablescsrfvalidation '=> true,
),
Csrf verification is performed on post requests globally. What should I do when I develop external interfaces? WeChat and Weibo do not work with your csrf mechanism. The only way is to disable csrf for these interface requests without affecting other services.
The idea was to disable csrf verification by changing the value of enableCsrfValidation somewhere, as I tried at the beginning:
Add the following code to the beforeAction or init method of the controller:
Yii: app ()-> request-> enableCsrfValidation = false;
Failed, failed, failed! The important thing is said three times.
What should Nima do? There is no way to waste time looking at the framework source code. It turns out that it is handled in CHttpRequest as follows:
If ($ this-> enableCsrfValidation)
Mod: app ()-> attachEventHandler ('onbeginrequest', array ($ this, 'validatecsrftoken '));
This Nima is directly put in the onBeginRequest event of the Application, because it is useless to do anything in the controller before the controller is loaded!
OK. Try:
Create a new MyApplication class that inherits CWebApplication and overwrite the onBeginRequest class. Use some judgments to bypass the validateCsrfToken action.
Obviously, solution 1 is too troublesome. I didn't want to touch it at all due to this poor event mechanism, so I adopted the following method.
My solution:
First, disable csrf in the configuration file.
'Request' => array (
'Enablescsrfvalidation '=> false, // disable it forcibly. Otherwise, the interface service is affected and transferred to the controller for manual verification.
),
Then, open components/Controller. php and write as follows:
Class Controller extends CController
{
Public $ enableCSRF = true; // whether to enable csrf verification
// Process before executing the action
Public function beforeAction ($ action)
{
$ This-> validateCsrfToken ();
Return parent: beforeAction ($ action );
}
// Verify csrf
Protected function validateCsrfToken ()
{
If ($ this-> enableCSRF = true ){
Mod: app ()-> request-> enableCsrfValidation = true; // The attribute is changed to true for CHtml: beginForm () to generate csrf_token.
Try {
Mod: app ()-> request-> validateCsrfToken (null); // verify csrf
} Catch (Exception $ e ){
Mod: app ()-> handleException ($ e );
}
}
}
}
The request is intercepted by beforeAction of the controller base class, and csrf verification is manually called through condition judgment. If a controller does not require csrf verification, set
Public $ enableCSRF = false;
You can disable verification.