When the user enters correctly with the access data to the system, it registers in the database failed attempts in the following tables.
failed_attempt This table posts every failed attempt as a registered or unregistered user, all failed attempts are counted.
failed_login This table records failed attempts of a user who is registered in the system obtaining his id - >
id_user
You should not record failed attempts in the tables, because the user entered the correct data and accessed the system, therefore you should not register failed attempts.
Failed attempts must be recorded when sending blank data, when a user is entered that does not exist, when a correct user is entered and a wrong password is entered. All this works correctly, the error is presented when accessing the system correctly registers failed attempts when it should not because you are accessing the system correctly.
The second error occurs in the session
, apparently the session
is being destroyed or it is not validating correctly when the user enters the data correctly in the login (login.php) this is redirected to the main page (index.php) everything seems to be perfect but it is not.
Because when modifying the Urls or clicking on the
<a href="login.php">Iniciar Sesión</a>
link to access the login.php page, I can accesslogin
and should not be able to enter thelogin
because I have already startedsesión
should redirect me back to the main page but it does not.
index.php
<?php
session_start();
/*if(!isset($_SESSION["id_user"])) {
header("location:login.php");
}*/
function logged_in(){
return (isset($_SESSION['id_user'])) ? true : false;
}
?>
<!doctype html>
<html lang="en">
<head>
</head>
<body>
<div class="boton">
<?php
if (logged_in() === true){
echo "Usuario logueado";
}else{
echo "usuario no logueao";
}
?>
</div>
<div><a href="login.php">iniciar sesion</a></div>
</body>
</html>
login.php
<?php
session_start();
if (isset($_POST)) {
$message= $username = $password = $usernameBD = $passwordDB = NULL;
$captcha = true;
//indicador usuario logueado
$logueado = false;
//Nro intentos permitidos para IP
$attemptsIP = 8;
//Nro intentos permitidos para Usuario
$attemptsU = 5;
if(isset($_POST) && isset($_POST["vcode"]) && $_POST["vcode"]!=$_SESSION["vcode"]) {
$captcha = false;
$message = "Los caracteres escritos no coinciden con la palabra de verificación. Inténtalo de nuevo.";
}else{
unset($_SESSION['id_user']);
}
$addres = $_SERVER['REMOTE_ADDR'];
//Conexión -> SQL
require_once'app/php/config.ini.php';
//Bloqueamos la ip por un día
$stmtA = $con->prepare("SELECT attempts FROM failed_attempt WHERE ip=? AND datetime BETWEEN DATE_SUB( NOW() , INTERVAL 1 DAY ) AND NOW()");
$stmtA->bind_param("s",$addres);
$stmtA->execute();
$stmtA->store_result();
//Variable para saber si existe registro o no para insert o update.
$check_result = $stmtA->num_rows;
if ($stmtA->num_rows===1) {
//if ($stmtA->num_rows>0) {
//Obtenemos datos para comparar intentos y para resetear intentos por su ultimo fecha.
$stmtA->bind_result($failed_login_attempt);
$stmtA->fetch();
$stmtA->close();
} else {
$stmtA->close();
$failed_login_attempt=0;
}
if(count($_POST)>0 && $captcha == true) {
$username = $_POST["username"] ?: '';
$password = $_POST["password"] ?: '';
//Buscar usuario ingresado - INICIO
$stmtB = $con->prepare("SELECT id_user,username,password,logindatetime, CASE WHEN logindatetime BETWEEN DATE_SUB( NOW() , INTERVAL 2 MINUTE ) AND NOW() THEN '1' ELSE '0' END as logueado FROM users where username=? AND active=? LIMIT 1");
$stmtB->bind_param("si",$username,$active);
$active=1;
$stmtB->execute();
$stmtB->store_result();
if ($stmtB->num_rows===1) {
$stmtB->bind_result($id_userBD,$usernameBD,$passwordDB,$logindatetime,$activeBD);
if ($stmtB->fetch()){
if (password_verify($password, $passwordDB)) {
$check_password = true;
} else {
$check_password = false;
}
} $stmtB->close();
} else {
$stmtB->close();
$check_password = false;
}
//Buscar usuario ingresado - FIN
//registra intentos de login segun IP - INICIO
//if ($check_username == false) {
if($check_result===0){
//Si es su primer intento fallido, incluimos el primer registro en la BD
$stmtC = $con->prepare("INSERT INTO failed_attempt (ip,attempts,datetime) VALUES (?, ?, NOW())");
$stmtC->bind_param("si",$addres,$attempts);
$attempts = 1;
//$datetime = date('Y-m-d H:i:s', time());
$stmtC->execute();
$stmtC->close();
} else {
//se actualiza mientras el nro de intentos este abierto, para evitar bug con calculo del dia bloqueado
if($failed_login_attempt<$attemptsIP){
$accountant = $failed_login_attempt + 1;
$stmtD = $con->prepare("UPDATE failed_attempt SET attempts=?, datetime=NOW() WHERE ip = ?");
$stmtD->bind_param("is",$accountant,$addres);
//$datetime = date('Y-m-d H:i:s', time());
$stmtD->execute();
$stmtD->close();
}
}
//}
//registra intentos de login segun IP - FIN
//VALIDANDO DOBLE LOGUEO
if ($username==$usernameBD && $check_password == true && $logindatetime!=NULL && $activeBD==1) {
$logueado = true;
} else {
//registra intentos segun usuario - INICIO
$attempU = 0;
if($usernameBD!= null && $usernameBD!=''){
$id_user = $id_userBD;
//Sentencia
$stmtE = $con->prepare("SELECT attempts FROM failed_login WHERE id_user =? AND datetime BETWEEN DATE_SUB( NOW() , INTERVAL 15 MINUTE ) AND NOW() ");
$stmtE->bind_param("i",$id_user);
$stmtE->execute();
$stmtE->store_result();
$queryResult = $stmtE->num_rows;
if ($queryResult===0) {
$stmtF = $con->prepare("INSERT INTO failed_login (id_user, attempts, ip, datetime) VALUES (?, ?, ?, NOW())");
$stmtF->bind_param("iis",$id_user,$attempts,$addres);
$attempts=1;
$stmtF->execute();
$stmtF->close();
} else {
$stmtE->bind_result($attempU_BD);
$stmtE->fetch();
$attempU = $attempU_BD+1;
if ($attempU_BD<$attemptsU) {
$stmtG = $con->prepare("UPDATE failed_login SET attempts=?, ip = ?, datetime=NOW() where id_user =?");
$stmtG->bind_param("isi",$attempU,$addres,$id_user);
$stmtG->execute();
$stmtG->close();
}
} $stmtE->close();
}
//registra intentos segun usuario - FIN
}
//validando Usuario y Contraseña - INICIO
if (empty($username) || empty($password)) {
$message = "Es necesario introducir un nombre de usuario y contraseña";
} elseif($failed_login_attempt>=$attemptsIP){
$message = "'IP' bloqueada por 1 dia";
} elseif($logueado){
$message = "'Usuario' ya se encuentra logueado.";
} elseif($attempU>=$attemptsU){
$message = "'Usuario' bloqueado por 15 minutos";
} elseif ($username != $usernameBD ) {
$message = "El 'Usuario' que has introducido no coincide. ";
} elseif ($check_password == false) {
$message = "Tu 'Contraseña' introducido no coincide. ";
} else {
$_SESSION["id_user"] = $id_userBD;
//$con->query("DELETE FROM failed_attempt WHERE ip = '$addres'");
//$con->query("DELETE FROM failed_login WHERE id_user ='$id_user'");
}
//validando Usuario y Contraseña - FIN
if(isset($_SESSION["id_user"])) {
//echo '<script>window.location="index.php"</script>';
header('location:index.php');exit;
}
}
}
?>
Note: By correctly entering the system and accessing the login.php that should not be able to because I have already logged in when returning to the main page it shows me the message not logged you are losing or destroying the
session
should not because there is not yet the code to destroy thesession