Yii2 CSRF's question (end)

Source: Internet
Author: User
    1. Describe your problem
      When the CSRF defense is turned on, the default value of CSRF can only be used once, the second commit is the validation does not pass, because already used, then how to do the following effect?

, the page is the AJAX submission request, then the first button click after the CSRF value is invalid, the second commit failed to return 400 error, solve!
How to let the value of CSRF be refreshed and used for a second request.

Don't let me close csrf,csrf to defend this request.

After the brother's guidance downstairs, now analyzed as follows,
When using his own form, \yii\helpers\BaseHtml::beginForm there is a judgment in the method that if you call form creation multiple times in a page display, the CSRF is the same every time you get it-that is, multiple forms on the same page are available.
We know that CSRF validation is in the \yii\web\Request class, but the class was initialized when I did not see that he had checked csrf, so we need to know where he was checking, through full-text search, and found that there were checks in the methods of the \yii\web\Controller class beforeAction , and the prototype was as follows:

/**     * @inheritdoc     */    public function beforeAction($action)    {        if (parent::beforeAction($action)) {            if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !Yii::$app->getRequest()->validateCsrfToken()) {                throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.'));            }            return true;        }                return false;    }

Through this code we know that in checking csrf is the method of direct use \yii\web\Request::validateCsrfToken , in which the method first loadCsrfToken obtains the CSRF,

 /** * Loads The CSRF token from cookie or session. * @return String The CSRF token loaded from cookie or session.     Null is returned if the cookie or session * Does not has CSRF token. */protected function Loadcsrftoken () {if ($this->enablecsrfcookie) {return $this->getcook        IES ()->getvalue ($this->csrfparam);        } else {return Yii:: $app->getsession ()->get ($this->csrfparam); }    }

This code is very well understood, that is, the cookie is taken, it is not opened in the session to take, and then return. The
then validates the CSRF token through the validatecsrftokeninternal method, which is discovered by tracking code that does not delete the csrf after validating csrf, in other words, the CSRF is still available, As long as your page does not refresh, because the page refreshes in the header of your layout file will have a !--? = Html::csrfmetatags ()?--> to output CSRF, the last csrf will be invalidated. So say a page constantly AJAX requests, as long as not refresh is no problem.
Conclusion:
There are several places in Yii that refresh csrf
\yii\helpers\basehtml::beginform , html::csrfmetatags () , \yii\web\request::getcsrftoken , key points in \yii\web\request::getcsrftoken method as the brothers downstairs said, The $regenerate parameter also controls forcing the CSRF token to be regenerated.

Private $_csrftoken;     /** * Returns The token used to perform CSRF validation.     * * This token was a masked version of [[Rawcsrftoken]] to prevent [BREACH attacks] (http://breachattack.com/). * This token is passed along via a hidden field of an HTML form or an HTTP header value * to support CSRF Validati     On. * @param boolean $regenerate whether to regenerate CSRF token. When this parameter are true, each time * This method is called, a new CSRF token would be generated and persisted (in S     Ession or cookies).     * @return String The token used to perform CSRF validation.            */Public Function Getcsrftoken ($regenerate = False) {if ($this->_csrftoken = = = NULL | | $regenerate) { if ($regenerate | |            ($token = $this->loadcsrftoken ()) = = = = NULL) {$token = $this->generatecsrftoken (); }//The mask doesn ' t need to be very random $chars = ' ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRS Tuvwxyz0123456789_-. ';            $mask = substr (Str_shuffle (Str_repeat ($chars, 5)), 0, static::csrf_mask_length); The + sign may decoded as blank space later, which would fail the validation $this->_csrftoken = Str_re        Place (' + ', '. ', Base64_encode ($mask. $this->xortokens ($token, $mask)));    } return $this->_csrftoken; }

The method in the acquisition of Csrftoken when the decision $this->_csrfToken is empty, according to the normal loading of the page program start is definitely empty, this value is not a client, this is not from the server, is the page is empty after startup, only after the implementation of the method generated CSRF Token will be put cookie in and, that is, session in the same request to execute the method multiple times, get the CSRF token is the same, if a new page request to the method will be regenerated, this is the different page refresh why CSRF token has always changed the reason, so, The CSRF token value can be used multiple times, but only for Ajax requests on the current page.

My system problem is because I am using IIS 10 as the Web, and the URL rewrite, the default non-existent files or folders will be rewritten to yii processing, but I did not place the legendary file in the Web directory favicon.ico , resulting in a 404, this is the browser in the background automatically request, Cause yii output a 404, and I do not know, 404 page and call the layout, resulting in CSRF token was refreshed. It's two.

Reply content:

    1. Describe your problem
      When the CSRF defense is turned on, the default value of CSRF can only be used once, the second commit is the validation does not pass, because already used, then how to do the following effect?

, the page is the AJAX submission request, then the first button click after the CSRF value is invalid, the second commit failed to return 400 error, solve!
How to let the value of CSRF be refreshed and used for a second request.

Don't let me close csrf,csrf to defend this request.

After the brother's guidance downstairs, now analyzed as follows,
When using his own form, \yii\helpers\BaseHtml::beginForm there is a judgment in the method that if you call form creation multiple times in a page display, the CSRF is the same every time you get it-that is, multiple forms on the same page are available.
We know that CSRF validation is in the \yii\web\Request class, but the class was initialized when I did not see that he had checked csrf, so we need to know where he was checking, through full-text search, and found that there were checks in the methods of the \yii\web\Controller class beforeAction , and the prototype was as follows:

/**     * @inheritdoc     */    public function beforeAction($action)    {        if (parent::beforeAction($action)) {            if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !Yii::$app->getRequest()->validateCsrfToken()) {                throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.'));            }            return true;        }                return false;    }

Through this code we know that in checking csrf is the method of direct use \yii\web\Request::validateCsrfToken , in which the method first loadCsrfToken obtains the CSRF,

/**     * Loads the CSRF token from cookie or session.     * @return string the CSRF token loaded from cookie or session. Null is returned if the cookie or session     * does not have CSRF token.     */    protected function loadCsrfToken()    {        if ($this->enableCsrfCookie) {            return $this->getCookies()->getValue($this->csrfParam);        } else {            return Yii::$app->getSession()->get($this->csrfParam);        }    }

This code is very well understood, that is, the cookie is taken, it is not opened in the session to take, and then return. The
then validates the CSRF token through the validatecsrftokeninternal method, which is discovered by tracking code that does not delete the csrf after validating csrf, in other words, the CSRF is still available, As long as your page does not refresh, because the page refreshes in the header of your layout file will have a !--? = Html::csrfmetatags ()?--> to output CSRF, the last csrf will be invalidated. So say a page constantly AJAX requests, as long as not refresh is no problem.
Conclusion:
There are several places in Yii that refresh csrf
\yii\helpers\basehtml::beginform , html::csrfmetatags () , \yii\web\request::getcsrftoken , key points in \yii\web\request::getcsrftoken method as the brothers downstairs said, The $regenerate parameter also controls forcing the CSRF token to be regenerated.

Private $_csrftoken;     /** * Returns The token used to perform CSRF validation.     * * This token was a masked version of [[Rawcsrftoken]] to prevent [BREACH attacks] (http://breachattack.com/). * This token is passed along via a hidden field of an HTML form or an HTTP header value * to support CSRF Validati     On. * @param boolean $regenerate whether to regenerate CSRF token. When this parameter are true, each time * This method is called, a new CSRF token would be generated and persisted (in S     Ession or cookies).     * @return String The token used to perform CSRF validation.            */Public Function Getcsrftoken ($regenerate = False) {if ($this->_csrftoken = = = NULL | | $regenerate) { if ($regenerate | |            ($token = $this->loadcsrftoken ()) = = = = NULL) {$token = $this->generatecsrftoken (); }//The mask doesn ' t need to be very random $chars = ' ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRS Tuvwxyz0123456789_-. ';            $mask = substr (Str_shuffle (Str_repeat ($chars, 5)), 0, static::csrf_mask_length); The + sign may decoded as blank space later, which would fail the validation $this->_csrftoken = Str_re        Place (' + ', '. ', Base64_encode ($mask. $this->xortokens ($token, $mask)));    } return $this->_csrftoken; }

The method in the acquisition of Csrftoken when the decision $this->_csrfToken is empty, according to the normal loading of the page program start is definitely empty, this value is not a client, this is not from the server, is the page is empty after startup, only after the implementation of the method generated CSRF Token will be put cookie in and, that is, session in the same request to execute the method multiple times, get the CSRF token is the same, if a new page request to the method will be regenerated, this is the different page refresh why CSRF token has always changed the reason, so, The CSRF token value can be used multiple times, but only for Ajax requests on the current page.

My system problem is because I am using IIS 10 as the Web, and the URL rewrite, the default non-existent files or folders will be rewritten to yii processing, but I did not place the legendary file in the Web directory favicon.ico , resulting in a 404, this is the browser in the background automatically request, Cause yii output a 404, and I do not know, 404 page and call the layout, resulting in CSRF token was refreshed. It's two.

If you do not have to go through a request without a manual call, there will be no problem with the Yii::$app->request->getCsrfToken(true) validation you said.

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.