Agiletoolkit Auth/basic 类允许无限制地尝试登录。我正在寻找一种方法来限制登录尝试失败的次数,我试图覆盖这个类的一些方法,但它使用 ajax 重新加载,所以 php 代码不能正确执行。
欢迎任何建议。
非常感谢,
Agiletoolkit Auth/basic 类允许无限制地尝试登录。我正在寻找一种方法来限制登录尝试失败的次数,我试图覆盖这个类的一些方法,但它使用 ajax 重新加载,所以 php 代码不能正确执行。
欢迎任何建议。
非常感谢,
我认为您可以使用 afterLoad 钩子在会话或 cookie 中存储 Model_User(通常在 Auth 中使用)的使用次数,然后在需要的地方检查它。
哎呀。登录失败。所以你的模型没有加载。您只需计算登录表单按钮的点击次数并将其存储在某处(cookies、数据库)。因此,创建您自己的登录表单并在提交表单时添加一些条件,例如:
$m = $this->add('Model_User');
$f = $this->add("Form");
$f->setModel($m, array('email', 'password'));
$f->addSubmit("Log In");
if ($f->isSubmitted()){
//Limmiting
if($_COOKIE[$this->api->name."_count_failed_login"] >= 5/*Here's you limit number*/){
/*redirect or something else*/
}
if (/*here should be you condition*/){
$_COOKIE[$this->api->name."_count_failed_login"] = 0;
$this->api->auth->login($f->get("email"));
$f->js()->univ()->redirect("index")->execute();
}else{
/* when login is failed*/
if($_COOKIE[$this->api->name."_count_failed_login"]){
$_COOKIE[$this->api->name."_count_failed_login"]++;
}else{
$_COOKIE[$this->api->name."_count_failed_login"] = 1;
}
$this->js()->univ()->alert('Wrong username or password')->execute();
}
}
我没有检查它。也许需要一些调整。只是一个想法。
希望有帮助。
受 StackOverflow 启发,我实现了以下保护:
我们为每个用户存储软/硬锁。即使密码正确,硬锁也会拒绝验证密码。软锁是一段时间后我们将重置“不成功尝试”计数器。每次您输入不正确的密码时,软锁和硬锁都会增加,让您等待更长时间(但不是永远)逐渐增加会设置一个合理的限制,因此如果您的攻击者试图破解您的帐户一个小时 - 他只会尝试几次,但您的几个小时后账户就可以登录了。我已经在我的一个项目中实现了这一点,尽管它不是控制器,而是内置代码。请浏览评论,我希望这会对您和其他人有所帮助:
在用户模型中添加:
$this->addField('pwd_locked_until');
$this->addField('pwd_failure_count');
$this->addField('pwd_soft_unlock');
您还需要两种方法:
/* Must be called when user unsuccessfully tried to log-in */
function passwordIncorrect(){
$su=strtotime($this['pwd_soft_unlock']);
if($su && $su>time()){
// aw, they repeatedly typed password in, lets teach them power of two!
$this['pwd_failure_count']=$this['pwd_failure_count']+1;
if($this['pwd_failure_count']>3){
$this['pwd_locked_until']=date('Y-m-d H:i:s',time()
+pow(2,min($this['pwd_failure_count'],20)));
$this['pwd_soft_unlock']=date('Y-m-d H:i:s',time()
+max(2*pow(2,min($this['pwd_failure_count'],20)),60*5));
}
}else{
$this['pwd_failure_count']=1;
$this['pwd_soft_unlock']=date('Y-m-d H:i:s',time() +60*5);
}
$this->save();
}
和
/* Must be called when user logs in successfully */
function loginSuccessful(){
$this['last_seen']=date('Y-m-d H:i:s');
$this['pwd_soft_unlock']=null;
$this->save();
}
最后 - 您可以将其用作登录表单:
class Form_Login extends Form {
function init(){
parent::init();
$form=$this;
$form->setModel('User',array('email','password'));
$form->addSubmit('Login');
if($form->isSubmitted()){
$auth=$this->api->auth;
$l=$form->get('email');
$p=$form->get('password');
// check to see if user with such email exist
$u=$this->add('Model_User');
$u->tryLoadBy('email',$form->get('email'));
// user may have also typed his username
if(!$u->loaded()){
$u->tryLoadBy('user_name',$form->get('email'));
}
// incorrect email - but say that password is wrong
if(!$u->loaded())$form->getElement('password')
->displayFieldError('Incorrect Login');
// if login is locked, don't verify password at all
$su=strtotime($u['pwd_locked_until']);
if($su>time()){
$form->getElement('password')
->displayFieldError('Account is locked for '.
$this->add('Controller_Fancy')
->fancy_datetime($u['pwd_locked_until']));
}
// check account
if($auth->verifyCredentials($u['email'],$p)){
// resets incorrect login statistics
$u->loginSuccessful();
$auth->login($l);
// redirect user
$form->js()->univ()->location($this->api->url('/'))->execute();
}else{
// incorrect password, register failed attempt
$u->passwordIncorrect();
$form->getElement('password')->displayFieldError('Incorrect Login');
}
}
}
}
这应该由某人转换为附加组件。