文章來自http://blog.crarun.com/article-7.htmlphp
在Yii框架中,爲了防止csrf攻擊,封裝了CSRF令牌驗證。html
只須要在主配置文件中進行簡單的配置,就能夠實現CSRF的驗證。安全
'components'=>array( 'request'=>array( // Enable Yii Validate CSRF Token 'enableCsrfValidation' => true, ), ),
將enableCsrfValidation設置爲true了以後,使用Yii表單生成頁面的時候,若是表單的提交方式爲POST,是都會在頁面中添加一個隱藏字段
本身寫的表單須要手動添加隱藏字段<div style="display:none"> <input type="hidden" value="a429b6c0f4468db23a5661d1682db537fe2672c7" name="YII_CSRF_TOKEN" /> </div>
用戶在提交表單的同時,將該字段提交給服務器端,Yii框架會將該有客戶端提交過來的隱藏字段和客戶端提交過來的Cookie中的 YII_CSRF_TOKEN值進行比較。相同則經過繼續執行,不相同則會拋出400異常:"The CSRF token could not be verified."。<input type="hidden" value="<?php echo Yii::app()->getRequest()->getCsrfToken(); ?>" name="YII_CSRF_TOKEN" />
重寫CHttpRequest:
建立一個類HttpRequest繼承於CHttpRequest,並將該類存放在 protected/components 下。
重寫CHttpRequest的 getCsrfToken() 和 validateCsrfToken($event) 方法。服務器
修改配置文件main.php:private $_csrfToken; // public function getCsrfToken() { if($this->_csrfToken===null) { $session = Yii::app()->session; $csrfToken=$session->itemAt($this->csrfTokenName); if($csrfToken===null) { $csrfToken = sha1(uniqid(mt_rand(),true)); $session->add($this->csrfTokenName, $csrfToken); } $this->_csrfToken = $csrfToken; } return $this->_csrfToken; } // public function validateCsrfToken($event) { if($this->getIsPostRequest()) { // only validate POST requests $session=Yii::app()->session; if($session->contains($this->csrfTokenName) && isset($_POST[$this->csrfTokenName])) { $tokenFromSession=$session->itemAt($this->csrfTokenName); $tokenFromPost=$_POST[$this->csrfTokenName]; $valid=$tokenFromSession===$tokenFromPost; } else $valid=false; if(!$valid) throw new CHttpException(400,Yii::t('yii','The CSRF token could not be verified.')); } }
'components' => array( 'request' => array( 'class' => 'application.components.HttpRequest', 'enableCsrfValidation' => true, ), ),