zoukankan      html  css  js  c++  java
  • yii2 关于csrf

    文章来自http://blog.crarun.com/article-7.html

    在Yii框架中,为了防止csrf攻击,封装了CSRF令牌验证。

    只需要在主配置文件中进行简单的配置,就可以实现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>

    自己写的表单需要手动添加隐藏字段
    <input type="hidden" value="<?php echo Yii::app()->getRequest()->getCsrfToken(); ?>" name="YII_CSRF_TOKEN" />
    用户在提交表单的同时,将该字段提交给服务器端,Yii框架会将该有客户端提交过来的隐藏字段和客户端提交过来的Cookie中的 YII_CSRF_TOKEN值进行比较。相同则通过继续执行,不相同则会抛出400异常:"The CSRF token could not be verified."。

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

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

    重写CHttpRequest:
    创建一个类HttpRequest继承于CHttpRequest,并将该类存放在 protected/components 下。
    重写CHttpRequest的 getCsrfToken() 和 validateCsrfToken($event) 方法。

    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.'));
        }
    }
    修改配置文件main.php:
       'components' => array(
            'request' => array(
                'class' => 'application.components.HttpRequest',
                'enableCsrfValidation' => true,
            ),
        ),
     
  • 相关阅读:
    第二次作业——结对项目之需求分析与原型模型设计
    Git进行代码管理的心得
    安卓开发环境演变
    软件工程的实践项目的自我目标
    若一切能重来
    随堂练习——Rational rose
    第五次软件个人作业
    第三次作业——结对编程
    第二次作业——结对项目之需求分析与原型模型设计
    软工实践练习——使用Git进行代码管理
  • 原文地址:https://www.cnblogs.com/yangbanban/p/5013519.html
Copyright © 2011-2022 走看看