Php Yii2根据条件添加规则
我正在使用PHP Yii2框架和dektrium\Yii2用户扩展构建一个网站,用于用户身份验证 如果不成功登录的次数超过三次,我想向用户索要验证码,但默认情况下扩展不支持这一点 现在,我已经覆盖了扩展的用户和LoginForm模型,并添加了所需的字段和检查。然而,我不知道如何添加一个规则,使验证码只需要从第四次尝试 是否可以动态添加规则?我在下面展示了一个简化的代码视图和我需要帮助的注释。我将写的功能,只是需要帮助与评论部分Php Yii2根据条件添加规则,php,dynamic,yii2,rules,Php,Dynamic,Yii2,Rules,我正在使用PHP Yii2框架和dektrium\Yii2用户扩展构建一个网站,用于用户身份验证 如果不成功登录的次数超过三次,我想向用户索要验证码,但默认情况下扩展不支持这一点 现在,我已经覆盖了扩展的用户和LoginForm模型,并添加了所需的字段和检查。然而,我不知道如何添加一个规则,使验证码只需要从第四次尝试 是否可以动态添加规则?我在下面展示了一个简化的代码视图和我需要帮助的注释。我将写的功能,只是需要帮助与评论部分 <?php namespace app\models\dek
<?php
namespace app\models\dektrium\user;
class LoginForm extends \dektrium\user\models\LoginForm
{
public $captcha;
public $need_captcha;
public function rules() {
$rules = parent::rules();
//This is how you'd normally add a rule, but this will require it for every login
//The following rule should be added from the login()
$rules[] = ['captcha', 'captcha', 'message' => 'Too many attempts. Captcha required.'];
$rules[] = ['need_captcha', 'boolean'];
return $rules;
}
public function login() {
$success = false;
$requireCaptcha = false;
if ($this->validate() && $this->user) {
if ($this->user->login_attempts > 3) {
//add rule here to require captcha
$requireCaptcha = true;
}
$success = !$requireCaptcha && $this->validateCaptcha() && $this->validateLogin();
if ($success) {
$this->user->updateAttributes(['last_login_at' => time()]);
}
}
return $success;
}
}
?>
以下是我最终如何做到这一点的
我使用了一个基于场景的规则,在控制器操作中,当我需要验证码的条件为真时,我设置了场景。实际上,控制器也是任意扩展的,因此我必须进行一些受支持的控制器映射,并通过事件设置场景
我第一次尝试这样做失败了,因为我在验证函数期间设置了场景,但可能应该在这样做之前设置它,因为它在哪里工作
<?php
namespace app\models\dektrium\user;
class LoginForm extends \dektrium\user\models\LoginForm
{
public $captcha;
public $need_captcha;
public $login_count;
public function rules() {
$rules = parent::rules();
$rules[] = ['captcha', 'required', 'on' => ['use_captcha']];
$rules[] = ['captcha', 'captcha', 'on' => ['use_captcha']];
$rules[] = ['need_captcha', 'boolean'];
$rules[] = ['login_count', 'integer'];
return $rules;
}
public function login() {
$success = true;
$this->user = $this->finder->findUserByUsernameOrEmail(trim($this->login));
if(!$this->need_captcha && $this->user && $this->user->login_count > 3) {
$this->need_captcha = true;
$success = false;
}
$success = $success && parent::login();
if ($success) {
$this->user->login_count = 0;
$this->user->save();
} else {
$this->login_count++;
if ($this->user) {
$this->user->login_count++;
$this->user->save();
}
if ($this->login_count > 2)
$this->need_captcha = true;
}
return $success;
}
}
使用
['field'、'required'、'when'=>函数($model){返回您的_true_条件;}
设置验证规则时
条件可以是session/cookie中的某个内容,比如每次递增的整数您可以共享操作的代码吗?您的规则是可疑的。如果您使用的是load()
在某个地方,用户可以将值传递给需要验证码
和登录计数
属性,并完全绕过验证码。@rob006这就是$this->user->login\u count的原因。所有失败的尝试都会记录到数据库中,并且login()从第三次尝试开始总是希望获得验证码。
<?php
namespace app\models\dektrium\user;
class LoginForm extends \dektrium\user\models\LoginForm
{
public $captcha;
public $need_captcha;
public $login_count;
public function rules() {
$rules = parent::rules();
$rules[] = ['captcha', 'required', 'on' => ['use_captcha']];
$rules[] = ['captcha', 'captcha', 'on' => ['use_captcha']];
$rules[] = ['need_captcha', 'boolean'];
$rules[] = ['login_count', 'integer'];
return $rules;
}
public function login() {
$success = true;
$this->user = $this->finder->findUserByUsernameOrEmail(trim($this->login));
if(!$this->need_captcha && $this->user && $this->user->login_count > 3) {
$this->need_captcha = true;
$success = false;
}
$success = $success && parent::login();
if ($success) {
$this->user->login_count = 0;
$this->user->save();
} else {
$this->login_count++;
if ($this->user) {
$this->user->login_count++;
$this->user->save();
}
if ($this->login_count > 2)
$this->need_captcha = true;
}
return $success;
}
}