登录添加验证码

技巧库 · echo · 于 1年前 发布 · 4388 次阅读

先上一张最终效果图

基本实现版

Yii 默认就带验证码功能,所以实现起来非常方便。

修改 Model 文件

找到 LoginForm.php 文件,添加如下代码:

<?php
namespace app\models;

use Yii;
use yii\base\Model;

class LoginForm extends Model
{
    // ...
    public $verifyCode;
    //...

    public function rules()
    {
        return [
            //...
            ['verifyCode', 'captcha']
        ];
    }
    
    //...
    
    public function attributeLabels()
    {
        return [
            //...
            'verifyCode' => '验证码',
        ];
    }

}

修改 Controller 文件

SiteController 文件添加如下代码:

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => ['signup', 'captcha'], // 授权验证码访问
                    'allow' => true,
                    'roles' => ['?'],
                ],
                [
                    'actions' => ['logout'],
                    'allow' => true,
                    'roles' => ['@'],
                ],
            ],
        ],
        //...
    ];
}

//...

public function actions()
{
    return [
        //...
        'captcha' => [
            'class' => 'yii\captcha\CaptchaAction',
            'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            'minLength' => 4,
            'maxLength' => 5,
        ],
    ];
}

修改 View 文件

视图 login 文件添加如下代码:

<?= $form->field($model, 'verifyCode')->widget(\yii\captcha\Captcha::className(), [
    'template' => '<div class="row"><div class="col-lg-7">{input}</div><div class="col-lg-4">{image}</div></div>',
    'imageOptions' => ['title' => '换一个', 'alt' => '验证码', 'style' => 'cursor:pointer;']
]); ?>

以上就是最基本的验证码功能使用。

完美体验版

但是一个体验好的网站一般首次登录不会出现验证码,如果连续登录失败超过 N 次才会提示输入验证码功能,如果你也想要此功能,请往下看。

给验证表验证一个场景

找到 LoginForm.php 文件,添加如下代码:

<?php
namespace app\models;

use Yii;
use yii\base\Model;

class LoginForm extends Model
{
    // ...
    public $verifyCode;
    public $attempts = 5; // 默认登录失败3次显示验证码
    public $counter;
    //...

    public function rules()
    {
        return [
            //...
            ['verifyCode', 'captcha', 'on' => 'captchaRequired']
        ];
    }
    
    //...
    
    public function attributeLabels()
    {
        return [
            //...
            'verifyCode' => '验证码',
        ];
    }
    
    //...
    
    // 修改登录方法
    public function login()
    {
        if ($this->validate() && Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0)) {
            Yii::$app->session->remove('loginCaptchaRequired');
            return true;
        } else {
            $this->counter = Yii::$app->session->get('loginCaptchaRequired') + 1;
            Yii::$app->session->set('loginCaptchaRequired', $this->counter);
            if ($this->counter >= $this->attempts) {
                $this->setScenario("captchaRequired");
            }
            return false;
        }
    }

}

修改 view 文件

视图 login 文件添加一个场景判断,如下代码:

<?php if ($model->scenario == 'captchaRequired'): ?>
    <?= $form->field($model, 'verifyCode')->widget(\yii\captcha\Captcha::className(), [
        'template' => '<div class="row"><div class="col-lg-7">{input}</div><div class="col-lg-4">{image}</div></div>',
        'imageOptions' => ['title' => '换一个', 'alt' => '验证码', 'style' => 'cursor:pointer;']
    ]); ?>
<?php endif ?>

至此,完成。

参考文档:

本文由 echo 创作,采用 知识共享署名 3.0 中国大陆许可协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。

本帖已被设为精华帖!
共收到 2 条回复 Yii2基本用法
tauonGit#11年前 0 个赞

你这个场景这里是怎么写的 ? 为什么我加了场景就报错呢

echo#21年前 0 个赞

@tauonGit #1楼 我这块没加,不加也可以。

添加回复 (需要登录)
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册