Cadastro e Login - #23 Verify Attempt Login
13/11/2018Neste vídeo vamos aprender como guardar a quantidade de tentativas errôneas de login executadas pelo usuário do site e bloquear caso ultrapasse a quantidade máxima.
Controlando quantidade de tentativas de login
Aliado ao captcha, o controle de tentativas de login é muito interessante para impedir que usuários fiquem tentando realizar combinações para burlar o sistema de login.
O primeiro passo dessa vídeo-aula é criar a TraitGetIp para pegarmos o ip do usuário que está realizando as tentativas de acesso:
<?php
namespace Traits;
trait TraitGetIp{
#Pegar o ip do usuário
public static function getUserIp()
{
$ipaddress = '';
if (getenv('HTTP_CLIENT_IP'))
$ipaddress = getenv('HTTP_CLIENT_IP');
else if(getenv('HTTP_X_FORWARDED_FOR'))
$ipaddress = getenv('HTTP_X_FORWARDED_FOR');
else if(getenv('HTTP_X_FORWARDED'))
$ipaddress = getenv('HTTP_X_FORWARDED');
else if(getenv('HTTP_FORWARDED_FOR'))
$ipaddress = getenv('HTTP_FORWARDED_FOR');
else if(getenv('HTTP_FORWARDED'))
$ipaddress = getenv('HTTP_FORWARDED');
else if(getenv('REMOTE_ADDR'))
$ipaddress = getenv('REMOTE_ADDR');
else
$ipaddress = 'UNKNOWN';
return $ipaddress;
}
}
Vamos acrescentar agora no model ClassLogin os métodos pra gerir as tentativas:
#Conta as tentativas
public function countAttempt()
{
$b=$this->selectDB(
"*",
"attempt",
"where ip=?",
array(
$this->trait
)
);
$r=0;
while($f=$b->fetch(\PDO::FETCH_ASSOC)){
if(strtotime($f["date"]) > strtotime($this->dateNow)-1200){
$r++;
}
}
return $r;
}
#Inseri as tentativas
public function insertAttempt()
{
if($this->countAttempt() < 5){
$this->insertDB(
"attempt",
"?,?,?",
array(
0,
$this->trait,
$this->dateNow
)
);
}
}
#Deleta as tentativas
public function deleteAttempt()
{
$this->deleteDB(
"attempt",
"ip=?",
array(
$this->trait
)
);
}
Na classe validate demos inicio ao método de validação de tentativas e o método de validação final do login:
#Validação das tentativas
public function validateAttemptLogin()
{
if($this->login->countAttempt() >= 5){
$this->setErro("Você realizou mais de 5 tentativas!");
$this->tentativas=true;
return false;
}else{
$this->tentativas=false;
return true;
}
}
#Validação final do login
public function validateFinalLogin($email)
{
if(count($this->getErro()) >0){
$this->login->insertAttempt();
}else{
$this->login->deleteAttempt();
}
}
Vamos criar na ClassValidate também a propriedade login e tentativas e fazer uma composição da ClassLogin:
private $login;
private $tentativas;
public function __construct()
{
$this->cadastro=new ClassCadastro();
$this->password=new ClassPassword();
$this->login=new ClassLogin();
}
Por fim, vamos chamar estes métodos no controllerLogin:
<?php
$validate=new Classes\ClassValidate();
$validate->validateFields($_POST);
$validate->validateEmail($email);
$validate->validateIssetEmail($email,"login");
$validate->validateStrongSenha($senha);
$validate->validateSenha($email,$senha);
$validate->validateCaptcha($gRecaptchaResponse);
$validate->validateAttemptLogin();
$validate->validateFinalLogin($email);
var_dump($validate->getErro());
Já vamos aproveitar e implementar o Captcha também no login. Ele basicamente vai utilizar o mesmo método do cadastro. Repare que já o chamamos no controller acima e agora precisamos colocar o input no formulário da nossa view login.
<input class="float w100 h40" type="hidden" id="g-recaptcha-response" name="g-recaptcha-response" required>