Abna 2019-04-01 11:16:56 3860次浏览 3条回复 1 1 0

昨天开始用 Yii2 做一个项目,需要用到图形验证码。

配置控制器行为

1554085580843.jpg

1554086992340.jpg

模型配置

1554085474708.jpg

我这里使用的客户端验证,服务器端验证关闭

if (!$this->validate(['username','password'])) { //指定验证字段,不验证verifyCode字段
    return null;
}
视图引用

视图文件中引用类 Captcha

use yii\captcha\Captcha;

form中开启客户端验证

<?php $form = ActiveForm::begin(['id' => 'form-signup','enableClientValidation'=>true]); ?>

引用验证码控件

<?= $form->field($model, 'verifyCode')->widget(
    Captcha::className(),
    [
        'captchaAction'=>'site/captcha',
        'imageOptions' => [ 'class' => "captcha"],
        'options' => ['placeholder' => '请输入验证码'],
    ]
)
?>

配置完成,我天真的以为这就 OK 了,刷新页面测试,不管你输入是否正确都报“验证码错误”。

经过一下午各种调试代码,最终才发现是session中根本没有验证码。

于是按照以下方法修改 yii\captcha\CaptchaAction 的源码:

1554087407386.jpg

这一步配置完,发现虽然有验证码,但是页面上显示的始终跟session中的对不上,于是:

1554087519602.jpg

最终效果:

1554088223663.jpg

到此,验证码就 OK 了。

注意:
  1. 这里是直接修改的Yii的源码,实际应用中最好自己写一个验证码类,继承CaptchaAction并且重写上面对应的方法。
  2. 另外如果需要在后台进行验证码验证,就在表单中关闭客户端验证,后端validate放行验证规则就行了。
  3. 具体为什么要这么改,我也不知道,有什么问题的话,请提出来,大家相互学习。
觉得很赞
  • 回复于 2019-04-01 11:46 举报

    如果需要前后端同时验证的话,像这样修改:

    public function validate($input, $caseSensitive)
    {
        $code = $this->getVerifyCode(false);
        $valid = $caseSensitive ? ($input === $code) : strcasecmp($input, $code) === 0;
        $session = Yii::$app->session;
        $session->open();
        $name = $this->getSessionKey() . 'count';
        $session->set($name ,$session->get($name) + 1);
        if ($valid || $session->get($name) > $this->testLimit && $this->testLimit > 0) {
            $this->getVerifyCode(true);
        }
    
        return $valid;
    }
    
    1 条回复
    回复于 2019-04-01 11:47 回复

    同样建议继承该类重写方法

  • 回复于 2019-04-01 21:19 举报

    这张图里面的 $session->get($name) === null 最好修改成 !$session->get($name)

    不然会存在刷新页面不刷新验证码的问题。

  • 回复于 2019-04-02 14:44 举报

    这个坑没填住,后面还要坑,已经准备自己重新写验证码模块了,各位别折腾了。

您需要登录后才可以回复。登录 | 立即注册