我正在使用PHP Yii2 Framework和dektrium \ yii2-user扩展名进行网站建设以进行用户身份验证。
我想询问用户验证码,如果登录失败次数超过三,但是默认情况下,扩展名不支持此操作。
现在,我已经覆盖了扩展程序的User和LoginForm模型,并添加了所需的字段和检查。但是,我无法弄清楚如何添加规则以仅从第四次尝试开始就需要验证码。
是否可以动态添加规则?我在下面显示了简化的代码视图以及需要帮助的地方。我将编写函数,只需要注释部分的帮助即可。
<?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;
}
}
?>
编辑:
如果有一个“可选”参数与“必需”相反,那么就足够了。我可以在我的login()中检查验证码。
编辑2:
我尝试使用以下方案,但是在进行验证之前,该模型未在控制器操作中加载验证码值。
<?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', 'captcha', 'message' => 'Too many attempts. Captcha required.', 'on' => ['required_captcha']];
$rules[] = ['need_captcha', 'boolean'];
$rules[] = ['login_count', 'integer'];
return $rules;
}
public function login() {
$this->user = $this->finder->findUserByUsernameOrEmail(trim($this->login));
if($this->user && $this->user->login_count > 3) {
$this->scenario = 'required_captcha';
$this->need_captcha = true;
}
$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 > 3) {
$this->scenario = 'required_captcha';
$this->need_captcha = true;
}
return $success;
}
}
答案 0 :(得分:1)
使用
设置验证规则时,GMTEXT
。
条件可以来自会话/ cookie,例如您每次都会增加的整数
答案 1 :(得分:-1)
所以这就是我最终完成此操作的方式...
我使用了基于场景的规则,并且在控制器操作中,当我需要验证码的条件为true时,设置了场景。实际上,控制器也可以进行任何扩展,因此我必须做一些受支持的控制器映射,并通过事件设置场景。
自从我在验证功能期间设置方案以来,我第一次尝试执行此操作失败,但是在执行此操作之前应该已经对其进行了设置。
<?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;
}
}