yii2 关于csrf

文章来自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" />

上面的方法是将客户端提交过来的值和客户端的Cookie中的值进行比较,并非最为安全的方法。

目前更为安全的方式,是将客户端提交过来的值和Session中的值进行比较,这就须要重写CHttpRequest类了。具体步骤以下:

重写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,
        ),
    ),
相关文章
相关标签/搜索