【问题标题】:CSRF token in Yii timing out?Yii 中的 CSRF 令牌超时?
【发布时间】:2015-04-01 12:46:15
【问题描述】:

我的 CSRF 令牌似乎超时了。有什么办法可以防止这种情况发生吗?

我有一个单页应用程序,我的前端是用 AngularJS 编写的。在大多数情况下,我的 CSRF 令牌验证良好,我可以确认我通过每个请求发送了令牌。但是,有时我会从我的服务器上看到“无法验证 CSRF 令牌”的错误。我不完全了解如何验证 CSRF 令牌的内部原理,但有什么原因会发生这种情况吗?

我们的应用程序也是国际化的,但由于我们的服务器基础设施,在某些地理区域出现了放缓。我注意到(只是临时),例如,如果用户正在上传文件并且请求花费的时间比平时长,那么 CSRF 令牌无效的可能性就更高。

很想听听关于这个的任何想法!提前致谢!

【问题讨论】:

  • 您是否为每个请求生成 CSRF 令牌?

标签: php yii csrf


【解决方案1】:

我认为 Yii 正在针对 cookie 验证 CSRF,尝试扩展 CHttpRequest 基类并针对会话进行验证。这会导致针对 CSRF 有效性的不同会话超时。

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));
                }
            }
        }
}

并在你的配置文件中使用它:

'request' => array(
            'enableCsrfValidation' => true,
            'class' => 'HttpRequest',

            'csrfCookie' => array(
                'httpOnly' => true,
                'secure' => true
            ),

注意:请勿复制粘贴所有内容。根据您的需要进行修改。这只是一个开始。希望我能理解你的问题。

【讨论】:

    猜你喜欢
    • 2016-05-06
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 2015-09-21
    • 2014-07-12
    • 1970-01-01
    相关资源
    最近更新 更多