YII 局部CSRF、令牌使用sessio存储

4 篇文章 0 订阅
YII 自带的CSRF功能很强大,每个form提交的数都会进行令牌验证,导致在接收支付宝同步通知时,被YII的CSRF功能挡之门外。项目中可能有些地方需要进行CSRF验证,但是有些地方又不需要。YII2在顶级控制器中添加了关闭csrf的一个属性:
/**
 * @var boolean whether to enable CSRF validation for the actions in this controller.
 * CSRF validation is enabled only when both this property and [[Request::enableCsrfValidation]] are true.
*/
 public $enableCsrfValidation = true;

但是yii2.0以下的版本是没有这个属性的。这是就得重写HttpRequest组件了。

<?php
class HttpRequest extends CHttpRequest{

    public $noCsrfValidationRoutes=array();

    //将CSRF令牌存入session
    /**
    +----------------------------------------------------------
     * 重写CHttpRequest中getCsrfToken方法
    +----------------------------------------------------------
     * author   fujia<@.com>
     * time     2015年4月27日20:47:54
    +----------------------------------------------------------
     */
    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;
    }

    //将使用session验证
    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.'));
        }
    }
    //重写httprequest中的方法
    protected function normalizeRequest()
    {
        parent::normalizeRequest();

        //remove the event handler CSRF if this is a route we want skipped
        if($this->enableCsrfValidation)
        {
            $url=Yii::app()->getUrlManager()->parseUrl($this);
            foreach($this->noCsrfValidationRoutes as $route)
            {

                if(strpos($url,$route)===0)

                $result = Yii::app()->detachEventHandler('onBeginRequest',array($this,'validateCsrfToken'));
            }
        }
    }


}
在配置文件中加:

'request'=>array(
			'class' => 'cfg_common.components.HttpRequest',
            'enableCsrfValidation'=>true,
            'enableCookieValidation'=>true,
            'noCsrfValidationRoutes'=>array(//不需要CSEF验证的URL
				'goods/cart',
				'goods/getOrder',
				'orders/notifyUrl',
				'orders/returnUrl',
				'orders/notifyUrlWap',
				'orders/returnUrlWap',
				'index/saveOrder',
			),
        ),
最后搞定


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值