Activate captcha after unsuccessful login attempts

Like gmail, if you have tree or more unsuccessful login attemps a captcha appears

But, how to do this with Yii ?

Modify your login Model like that

class LoginForm extends CFormModel {
	 ....
	 public $verifyCode;
	 
	 public function rules() {
        return array(
            array('username, password', 'required'),
            array('rememberMe', 'boolean'),
            array('password', 'authenticate'),
            array('verifyCode', 'captcha', 'allowEmpty' => !CCaptcha::checkRequirements(), 'on' => 'withCaptcha'), //only on withCaptcha scenario
        );
    ....

In your controller

public function actionLogin() {
        
        $model = new LoginForm;
        if (Yii::app()->user->getState('attempts-login') > 3) { //make the captcha required if the unsuccessful attemps are more of thee
            $model->scenario = 'withCaptcha';
        }
		
        if (isset($_POST['LoginForm'])) {
            $model->attributes = $_POST['LoginForm'];

            if ($model->validate() && $model->login()) {
                Yii::app()->user->setState('attempts-login', 0); //if login is successful, reset the attemps
                $this->controller->redirect(Yii::app()->user->returnUrl);
            } else {  //if login is not successful, increase the attemps 
                Yii::app()->user->setState('attempts-login', Yii::app()->user->getState('attempts-login', 0) + 1);

                if (Yii::app()->user->getState('attempts-login') > 3) { 
                    $model->scenario = 'withCaptcha'; //useful only for view
                }
            }
        }
        
        $this->render('login', array('model' => $model));
    }
Finally in your view login add this to the form


<?php if ($model->scenario == 'withCaptcha' && CCaptcha::checkRequirements()): ?>
            <div class="row">
                <?php echo $form->labelEx($model, 'verifyCode'); ?>
                <div>
                    <?php $this->widget('CCaptcha'); ?>
                    <?php echo $form->textField($model, 'verifyCode'); ?>
                </div>
                <?php echo $form->error($model, 'verifyCode'); ?>
            </div>
        <?php endif; ?>

4 1
16 followers
Viewed: 25 767 times
Version: 1.1
Category: How-tos
Last updated by: Rohit Suthar
Created on: Jun 20, 2013
Last updated: 3 years ago
Update Article

Revisions

View all history

Related Articles