Yii 登陆失败 一定次数 显示验证码

本文介绍如何在Yii框架中实现登录失败多次后显示验证码的功能。主要分为三步:在模型中添加验证码验证规则;控制器中根据失败次数使用不同模型;视图中动态显示验证码。

原文  http://www.yiiframework.com/wiki/339/show-captcha-after-n-unsuccessfull-attempts/

In this mini howto I would like to show how to add a required captcha field in the login form, after a defined number of unsuccessfull attempts. To do this, I will use the blog demo that you have in default Yii download package (path/to/yii/demos/blog).

在这篇文章中,我将展示如果在用户登陆失败若干次之后,要求用户输入验证码。我将用yii 自带的blog demo来做演示。

Basically, you need three things:

  • in the model, you have to add captcha field as a required field in the rules() method

  • in the controller, you have to create a different LoginForm model if number of unsuccessfull attempts are greater than N

  • in the view, you have to show captcha field if number of unsuccessfull attempts are greater than N

开始之前,你需要这三样东西:

  • 在model中,你在rules()中加一个captcha的验证规则
  • 在controller中,你要新建一个不同的LoginForm model,如果用户失败登陆的次数大于某个数N
  • 在view中,你要把captcha展示出来,如果用户失败登陆的次数大于某个数N

In the LoginForm model, you can use 'scenario' to set different required fields, so:

在LoginForm model,中你可以用'scenario'来设置不同‘scenario’中需要启动的验证规则,如下所示

public function rules()
        {
                return array(
                        // username and password are required
                        array('username, password', 'required'),
                        // rememberMe needs to be a boolean
                        array('rememberMe', 'boolean'),
                        // password needs to be authenticated
                        array('password', 'authenticate'),
                        // add these lines below                    
array('username,password,verifyCode','required','on'=>'captchaRequired'),
                        array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements()),         
                 );
        }

Moreover, add verifyCode as public property:

而且在model中,添加public property ,verifyCode

public $verifyCode;

In the view, add this code (show captcha field if scenario is set to 'captchaRequired', will see later):

在view中,添加下面的代码,(展示captcha如果model的scenario是'captchaRequired',之后我们会看到如何设置,model的‘scenario’)

<?php if($model->scenario == 'captchaRequired'): ?>
        <div class="row">
                <?php echo CHtml::activeLabelEx($model,'verifyCode'); ?>
                <div>
                <?php $this->widget('CCaptcha'); ?>
                <?php echo CHtml::activeTextField($model,'verifyCode'); ?>
                </div>
                <div class="hint">Please enter the letters as they are shown in the image above.
                <br/>Letters are not case-sensitive.</div>
        </div>
        <?php endif; ?>

Now, the controller. First, add a property to set maximum allowed attempts and a counter that trace failed attempts time to time:

现在,在controller中,我们添加一个property来设置前面提到的登陆失败的次数N,在controller里是$attempts,同时添加一个counter来记录用户失败登陆的次数。

public $attempts = 5; // allowed 5 attempts
public $counter;

then, add a private function that returns true if 'captchaRequired' session value is greater than number of failed attempts.

然后,添加一个private function capchaRequired(),只当‘captchaRequired’session 的值大于失败登陆的次数时,返回true.

private function captchaRequired()
        {           
                return Yii::app()->session->itemAt('captchaRequired') >= $this->attempts;
        }

We will use this function to know if captcha is required or not. Now, remain to modify actionLogin() method:

我们可以用这个function来判断captcha是否需要。现在我们来修改actionLogin() method:

public function actionLogin()
        {
                $model = $this->captchaRequired()? new LoginForm('captchaRequired') : new LoginForm;
 
                // if it is ajax validation request
                if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
                {
                        echo CActiveForm::validate($model);
                        Yii::app()->end();
                }
 
                // collect user input data
                if(isset($_POST['LoginForm']))
                {
                        $model->attributes=$_POST['LoginForm'];
                        // validate user input and redirect to the previous page if valid
                        if($model->validate() && $model->login())
                                $this->redirect(Yii::app()->user->returnUrl);
                        else
                        {
                                $this->counter = Yii::app()->session->itemAt('captchaRequired') + 1;
                                Yii::app()->session->add('captchaRequired',$this->counter);
                       }
                }
                // display the login form
                $this->render('login',array('model'=>$model));
        }

Note that:

  • if function captchaRequired() returns true create LoginForm with scenario 'captchaRequired', else create LoginForm with default scenario. This is useful because in protected/models/LoginForm.php we have set two different required fields depending on scenario:
注意,
如果function captchaRequired()返回true,我们将以scenario 'captchaRequired' create LoginForm,否则以默认的scenario来create LoginForm.这个非常有用,因为在protected/models/LoginForm.php中,我们对于不同的scenario,我们会有不同的表单输入项。
public function rules() 
        {               
                return array(
                        array('username, password', 'required'),
array('username,password,verifyCode','required','on'=>'captchaRequired'),
[... missing code...]
        }
  • if validation passes redirect to a specific page, but what if validation doesn't pass? In this case we increment the counter, then set a session named 'captchaRequired' with counter value, in this way:
  • 如果验证通过了,我们跳转到特定的页面,如果验证失败了,我们怎么做呢,这种情况下我们需要让我们的counter递增,然后设置一个名为'captchaRequired'的session值,代码如下
if($model->validate() && $model->login())
     $this->redirect(Yii::app()->user->returnUrl);
     else
     {
     $this->counter = Yii::app()->session->itemAt('captchaRequired') + 1;
     Yii::app()->session->add('captchaRequired',$this->counter);
     }

When 'captchaRequired' session will be equal to maximum allowed attempts (property $attempts) private function captchaRequired() will return true and then LoginForm('captchaRequired') will be created. With scenario set to 'captchaRequired' captcha will be show in the view:

当'captchaRequired' session 等于最大允许失败次数(property $attempts)时,private function captchaRequired()将会返回true,从而LoginForm('captchaRequired')将被create.在‘captchaRequired’ scenario下,captcha将显示出来,

<?php if($model->scenario == 'captchaRequired'): ?>
// code to show captcha
<?php endif; ?>

Easy, uh? ;)

很容易哈~ , :)


引用 

http://www.yiiframework.com/forum/index.php/topic/21561-captcha-custom-validation

http://drupal.org/node/536274


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值