dongqing8765 2015-04-01 01:35
浏览 140

Yii中的CSRF令牌超时?

My CSRF token seems to be timing out. Is there any way to prevent this?

I have a single page app where my frontend is written in AngularJS. For the most part, my CSRF token's validate fine and I can confirm that I send the token in through every request. However, occasionally I will see errors from my server saying that "The CSRF token could not be verified". I do not fully understand the internals of how the CSRF token is verified, but is there any reason for why this would be happening?

Our application is also international, but because of our server infrastructure there is slowdown in certain geographical areas. I've noticed (just ad-hoc) that if, for example, the user is uploading a file and the request takes longer than usual, the chances of the CSRF token being invalid is higher.

Would love to hear any ideas about this! Thanks in advance!

  • 写回答

1条回答 默认 最新

  • duandai0373 2015-04-01 04:46
    关注

    I think Yii is validing CSRF against cookie, try extending the CHttpRequest base class and validate against session. This leads to the varying session time out against CSRF validity.

    class HttpRequest extends CHttpRequest
    {
        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;
    
                    $headers = Common::getAllHeaders();
    
                    if ($session->contains($this->csrfTokenName) && (isset($_POST[$this->csrfTokenName]) || isset($headers['X-Csrf-Token']))) {
                        $tokenFromSession = $session->itemAt($this->csrfTokenName);
                        $tokenFromPost = isset($_POST[$this->csrfTokenName]) ? $_POST[$this->csrfTokenName] : $headers['X-Csrf-Token'];
                        $valid = $tokenFromSession === $tokenFromPost;
                    } else {
                        $valid = false;
                    }
                    if (!$valid) {
                        header("Location: " . Yii::app()->createAbsoluteUrl(Yii::app()->request->url));
                    }
                }
            }
    }
    

    And use it as in your config file:

    'request' => array(
                'enableCsrfValidation' => true,
                'class' => 'HttpRequest',
    
                'csrfCookie' => array(
                    'httpOnly' => true,
                    'secure' => true
                ),
    

    Note: Donot copy and paste all the content. Modify as per your need. This is just a start. Hope i understand your problem.

    评论

报告相同问题?

悬赏问题

  • ¥20 模型在y分布之外的数据上预测能力不好如何解决
  • ¥15 processing提取音乐节奏
  • ¥15 gg加速器加速游戏时,提示不是x86架构
  • ¥15 python按要求编写程序
  • ¥15 Python输入字符串转化为列表排序具体见图,严格按照输入
  • ¥20 XP系统在重新启动后进不去桌面,一直黑屏。
  • ¥15 opencv图像处理,需要四个处理结果图
  • ¥15 无线移动边缘计算系统中的系统模型
  • ¥15 深度学习中的画图问题
  • ¥15 java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条