0

我有 3 个控制器,分别命名为站点、广告和消息。所有控制器都有验证码动作类定义,并且它们在每个控制器的访问规则中都被允许。

验证码在站点控制器中运行良好,但在其他控制器中其验证不起作用。它显示验证码图像和重新验证码也可以工作,但只是验证不起作用,有什么想法可以调试吗?

更新 :

我调查了 Yii 并发现了一些东西。CCaptcha 小部件使用控制器名称作为会话密钥的一部分来存储验证码。

CCaptchaAction.php

protected function getSessionKey(){
    return self::SESSION_VAR_PREFIX . Yii::app()->getId() . '.' .   $this->getController()->getUniqueId() . '.' . $this->getId();
}

如您所见,$this->getController()->getUniqueId()session key 的一部分

CCaptchaAction 使用此函数生成验证验证码。

问题是生成验证发生在不同的控制器中。

在一个清晰的示例中,假设我们有控制器AB

当在控制器A中生成验证码时, print_r($_SESSION) 类似于:

数组 ( [Yii.CCaptchaAction.12bd9136. A .captcha] => eyntri [Yii.CCaptchaAction.12bd9136. A .captchacount] => 1

并且当控制器B中发生验证码验证时,验证方法会检查是否

New 在控制器 B 中生成并显示代码=== $_SESSION[Yii.CCaptchaAction.12bd9136. .captcha ] 是真是假。

当生成器和验证器控制器不相同时,它们并不总是相等的!

4

2 回答 2

5
  1. 在模型验证规则中指定captchaAction准确指向您的控制器验证码操作:

    array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements(), 'captcaAction' => 'site/captcha'),

  2. 在再次使用 capthca 小部件时的视图中,通过以下方式准确指向您的控制器验证码操作captchaAction

    <?php $this->widget('CCaptcha', array('captchaAction' => 'site/captcha')); ?>

于 2013-10-30T00:08:47.873 回答
0

我认为我的漏洞问题是 CCaptchaAction 使用控制器名称来命名会话密钥来存储验证密钥

最后,作为一个不错的解决方案,我通过以下类重载了 CCaptchaAction:

class CCaptchaActionExtension extends CCaptchaAction{
    protected function getSessionKey(){
           return self::SESSION_VAR_PREFIX . Yii::app()->getId() . '.' . $this->getId();
    }
}

在 CCaptchaAction 中,我在所有控制器中都使用了 CCaptchaActionExtention :

    public function actions()
    {
        return array(
            'captcha'=>array(
                'class'=>'CCaptchaActionExtension',
                'backColor'=>0xFFFFFF,
            ),   
        );
    }

如您所见,新类重载了getSessionKey()方法。因为控制器的名称困扰了我,所以我删除了它。

我不接受我的解决方案,因为我想听听您对此的评论或新的更好的解决方案(如果存在;:))

于 2013-10-27T22:43:14.650 回答