2013-10-04 5 views
1

Агилетный класс Auth/basic класс позволяет пробовать войти в систему без каких-либо ограничений. И я ищу способ ограничить количество неудачных попыток входа в систему, я попытался переопределить некоторые методы этого класса, но он использует перезагрузку ajax, поэтому PHP-код выполняется неправильно.Agiletoolkit Максимальное количество неудачных попыток входа в систему

Любое предложение приветствуется.

Большое спасибо,

ответ

1

Вдохновленный StackOverflow я реализовал следующую защиту:

для каждого пользователя мы храним мягкий/жесткий замок. Жесткий замок откажется проверять пароль, даже если он правильный. soft lock - это период времени, после которого мы сбросим счетчик «неудачных попыток». каждый раз, когда вы вводите неверный пароль, как мягкий, так и жесткий блокировки, заставляя вас ждать дольше (но не навсегда) постепенное увеличение дает разумный предел, поэтому, если ваш злоумышленник пытается взломать вашу учетную запись на час - у него будет только несколько попыток, но ваша учетная запись будет в порядке после входа в систему через несколько часов. Я реализовал это в одном из своих проектов, хотя это не контроллер, а встроенный код. Посмотрите, пожалуйста, в комментариях, и я надеюсь, что это поможет вам и другим:

В модели пользователя Добавить:

$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'); 
     } 
    } 
    } 
} 

Это должно быть преобразовано в дополнение кем-то.

1

Я думаю, что вы можете хранить номера использования Model_User (обычно используется в Auth) в сессии или печенье с помощью постнагрузки крючка, а затем проверить его там, где вам нужно.

К сожалению. НЕИСПРАВНОСТЬ. Таким образом, вы не загружаете модель. Вам нужно просто подсчитывать клики на кнопке формы входа и хранить ее где-нибудь (файлы cookie, база данных). Поэтому создайте свою собственную форму для входа и добавьте некоторое условие при отправке формы:

$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(); 
     } 
    } 

Я не проверял. Возможно, нужны некоторые корректировки. Просто идея.

Надеюсь, что это поможет.

Смежные вопросы