自定义Captcha

标准的Yii验证码已经足够防护垃圾信息,但是有些情况下,你可能需要自定义验证码,例如:

  • 你面对一个垃圾机器人,它可以从图片中读取文字,你需要添加更多的安全措施
  • 你希望让验证码更加简单和有趣

在我们的例子中,我们将会修改Yii的验证码,它要求用户解决一个简单的算术问题,而不只是简单的重复图片中文字的内容。

准备

这个例子一开始,我们会利用添加和自定义CaptchaWidget的结果。或者也可以使用其它使用了验证码的表单,因为我们不需要修改很多已有的代码。

如何做...

我们需要自定义CaptchaAction,它会生成验证码并将其生成图片。这个验证码应该是一个随机数字,并且图片应该是一个有相同结果的算术表达式:

  1. 创建@app/components/MathCaptchaAction.php
<?php
namespace app\components;
use \Yii;
use yii\captcha\CaptchaAction;
class MathCaptchaAction extends CaptchaAction
{
    protected function renderImage($code)
    {
        return parent::renderImage($this->getText($code));
    }
    protected function generateVerifyCode()
    {
        return mt_rand((int)$this->minLength,
            (int)$this->maxLength);
    }
    protected function getText($code)
    {
        $code = (int) $code;
        $rand = mt_rand(1, $code-1);
        $op = mt_rand(0, 1);
        if ($op) {
            return $code - $rand . " + " . $rand;
        }
        else {
            return $code + $rand . " - " . " " . $rand;
        }
    }
}
  1. 在我们的控制器actions方法中,我们需要将CaptchaAction替换成自己的验证码动作,如下:
public function actions()
{
    return [
        'captcha' => [
            'class' => 'app\components\MathCaptchaAction',
            'minLength' => 1,
            'maxLength' => 10,
        ],
    ];
}
  1. 运行你的表单,尝试新的验证码。它将会展示一个算术表达式,你需要输入它的答案,如下截图所示:

我们重写了两个CaptchaAction方法,在generateVerifyCode()中,我们生成了一个随机数而不是文本。然后我们需要渲染的是一个表达式,而不是文本,我们需要重写renderImage。表达式是由我们自定义getText()方法生成的。$minLength$maxLength属性已经在CaptchaAction定义了,所以我们不需要将它们加入到MathCaptchaAction类中。

参考

欲了解更多信息,参考如下链接:

results matching ""

    No results matching ""