我有 3 个控制器,名为 Site、Ads 和 Message。所有控制器都有验证码操作类定义,并且每个控制器的访问规则中都允许它们。
验证码在站点控制器中运行良好,但在其他控制器中,其验证不起作用。它显示验证码图像和重新验证码也可以工作,但只是验证不起作用,有什么想法要调试吗?
更新:
我探查了一下,发现了一些东西。CCaptcha 小组件使用控制器名称作为会话密钥的一部分来存储验证码验证码。
CCaptchaAction.php
protected function getSessionKey(){
return self::SESSION_VAR_PREFIX . Yii::app()->getId() . '.' . $this->getController()->getUniqueId() . '.' . $this->getId();
}
如您所见$this->getController()->getUniqueId() 是会话密钥的一部分。
CCaptchaAction 使用此函数生成和验证验证码。
问题是生成和验证发生在不同的控制器中。
在一个清晰的例子中,假设我们有控制器 A 和 B .
当验证码生成在控制器 A 中被占用时,print_r($_SESSION) 是这样的:
Array ( [Yii.CCaptchaAction.12bd9136.A.captcha] => eyntri [Yii.CCaptchaAction.12bd9136.A.验证码] => 1
当控制器 B 中发生验证码验证时,验证方法会检查是否
新 在控制器 B 中生成并显示代码 === $_SESSION[Yii.CCaptchaAction.12bd9136.A.验证码]是真的还是假的。
当生成器和验证器控制器不同时,它们并不总是相等的!!
-
在模型验证规则中,指定
captchaAction
以精确指向控制器验证码操作:array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements(), 'captcaAction' => 'site/captcha'),
-
在再次使用 capthca 小部件的视图中,通过
captchaAction
精确指向您的控制器验证码操作:<?php>widget('CCaptcha', array('captchaAction' => 'site/captcha')); ?>
我认为我的漏洞问题是 CCaptchaAction 使用控制器的名称来命名会话密钥来存储验证密钥。
最后,作为一个不错的解决方案,我通过以下类重载了CCaptchaAction:
class CCaptchaActionExtension extends CCaptchaAction{
protected function getSessionKey(){
return self::SESSION_VAR_PREFIX . Yii::app()->getId() . '.' . $this->getId();
}
}
在 CCaptchaAction 的 insead 中,我在所有控制器中使用了 CCaptchaActionExtensionion:
public function actions()
{
return array(
'captcha'=>array(
'class'=>'CCaptchaActionExtension',
'backColor'=>0xFFFFFF,
),
);
}
如您所见,新的类重载getSessionKey()方法。因为控制器的名称困扰了我,所以我删除了它。
我不接受我的解决方案,因为我想听听您对它的评论或新的更好的解决方案(如果存在; :) )