Foros del Web » Programando para Internet » PHP »

Bloquear usuario por un tiempo determinado luego de intentos fallidos

Estas en el tema de Bloquear usuario por un tiempo determinado luego de intentos fallidos en el foro de PHP en Foros del Web. Buenas.. como dice el titulo... he desarrollado y aggiornado codigos para el login de usuarios cuya fuente adjunto mas abajo.. Hace todo bien, pero no ...
  #1 (permalink)  
Antiguo 09/01/2012, 06:47
Avatar de loncho_rojas
Colaborador
 
Fecha de Ingreso: octubre-2008
Ubicación: En el mejor lugar del mundo
Mensajes: 2.704
Antigüedad: 16 años, 1 mes
Puntos: 175
Bloquear usuario por un tiempo determinado luego de intentos fallidos

Buenas.. como dice el titulo... he desarrollado y aggiornado codigos para el login de usuarios cuya fuente adjunto mas abajo..

Hace todo bien, pero no se me ocurre como hacer para bloquear a un usuario luego de 5 intentos fallidos... ya he logrado contabilizar los intentos fallidos, pero quisiera que cuando el limite llegue a 5, no se vuelva a habilitar la opcion de logueo para ese usuario por 24hs a partir de la fecha del ultimo intento fallido.

En mi tabla existen un campo INTENTOS, otro campo ULTIMAVISITA (timestamp) y un campo ULTIMOINTENTO (timestamp)... por favor si alguien me ayuda para lograr bloquear por 24hs o X tiempo a un usuario segun lo guardado en la BD.

Puede modificar lo que quieran del codigo.. ah.. si bien trabajo con Postgres, solo se cambian las funciones de pg_query por mysql_query, asi que es igual:

Aqui mi codigo funcionando a medias con ese pequeño detalle:
Código PHP:

<?php    
        
if($_POST){
            
            
$email $_POST["username"];
            
$clave $_POST["password"];
            
$fechadate("d/m/y H:i a");
            unset(
$_POST); //Se destruye el array $_POST
            
            
if(preg_match("/^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$/"$email)){
                
                
$sql_login="SELECT * FROM usuarios WHERE email LIKE '".$email."'";        
                
$resultado_login=pg_query($sql_login)or die("Error query ".pg_last_error());
                
                if(
pg_num_rows($resultado_login) == 1){
                    
                    
$fila_usuario=pg_fetch_array($resultado_loginnullPGSQL_ASSOC);
                    
                     if(
$fila_usuario['intentos'] < 5){
                         
                         if(
$fila_usuario['pass']== $clave){
                             
                                 
//validamos si la cuenta ya esta verificada 
                                
if($fila_usuario["verificacion"]=="si")
                                {
                                    
                                    
session_start();
                                    
$_SESSION["k_username"] = $fila_usuario["nombres"].", ".$fila_usuario["apellidos"];
                                    
$_SESSION["k_idcliente"] = $fila_usuario["idcliente"];
                                    
                                    
                                    
                                    
pg_query($conn2"UPDATE usuarios SET ultimavisita='".$fecha."', intentos='0' WHERE idcliente=".$fila_usuario['idcliente'])or die("Error query ".pg_last_error());
                                    
                                    
header("Location: ../clients/principal-clients.php");
            
                                }
//caso contrario, tiramos un mensaje de que aun no ha sido verificada la cuenta
                                
else
                                {
                                    echo 
"<h1>Su cuenta aun no ha sido verificada.</h1>";
                                    echo 
"<p>Si ya se ha registrado desde nuestro sitio Web:</p>";
                                    echo 
"<ul>
                                            <li>Por favor, revise su correo electrónico.</li>
                                            <li>Siga las instrucciones que le hemos enviado.</li>
                                            <li>Inicie Sesi&oacute;n.</li>
                                          </ul>"
;
                                    echo 
"<p>Caso contrario, puede <a href='registro.php'>registrarse</a> para acceder a los servicios</p>";
                                }
                             
                         
                         }else{
                             
pg_query($conn2"UPDATE usuarios SET ultimointento='".$fecha."', intentos=intentos+1 WHERE idcliente=".$fila_usuario['idcliente'])or die("Error query ".pg_last_error());
                             
                             echo 
"<p style='font-size:14px; color:#FF0000;'>El password no es valido!!</p>";
                             
                             
                             
$cn pg_query("SELECT intentos FROM usuarios WHERE idcliente=".$fila_usuario['idcliente'])or die("Error query ".pg_last_error());
                             
$rspg_fetch_array($cn);
                            
                             echo 
"<p>Recuerde que s&oacute;lo posee <strong>5 intentos</strong> para ingresar a su cuenta correctamente.</p>";
                             echo 
"<p>Este es su intento N&deg;: <span style='font-size:15px;'>".$rs['intentos']."</span></p>";
                             
                         }
                         
                         
                         
                         
                     }else{
                         echo 
"<p style='font-size:14px; color:#FF0000;'>Ha sobre pasado el limite de 5 intentos. <br />La cuenta sera bloqueada automaticamente por 24hs.</p>";
                     }
                     
                     
                    
                }else{
                    echo 
"<p>La direccion de email ingresada no esta registrada</p>";
                }
                
                
            
            }else{
                echo 
"<p>Ingrese una direccion de email valida</p>";
            }
            
            
            
        }else{
            
            
header("Location: ../index.php");
        }
        
        
?>
__________________
Ayudo con lo que puedo en el foro, y solo en el foro.. NO MENSAJES PRIVADOS.. NO EMAILS NI SKYPE u OTROS.

Antes de hacer un TOPICO piensa si puedes hallarlo en Google o en el Buscador del Foro...
  #2 (permalink)  
Antiguo 09/01/2012, 07:10
Avatar de linuxzero  
Fecha de Ingreso: noviembre-2011
Ubicación: Argentina
Mensajes: 778
Antigüedad: 13 años
Puntos: 160
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

Es cuestion de hacer una consulta a la base cuando va a autenticar que si los intentos son igual a 5 verificar el timestamp del horario del ultimo intento y validarlo contra el timestamp de la fecha actual, si no transcurrieron 24 horas, no autenticarlo y listo. Caso contrario, setear el intentos en 0 y la fecha del ultimo intento en null y autenticarlo. Aunque yo tendria un campo de intento_fallido y ultima_visita solamente y trabajaria con esos, mas que con 3 campos.
__________________
Si todo fuera tan sencillo como un symfony cc la vida seria más fácil.
http://phpnico.wordpress.com
  #3 (permalink)  
Antiguo 09/01/2012, 07:15
Avatar de loncho_rojas
Colaborador
 
Fecha de Ingreso: octubre-2008
Ubicación: En el mejor lugar del mundo
Mensajes: 2.704
Antigüedad: 16 años, 1 mes
Puntos: 175
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

el tema es que no se como hacer ese calculo de comparacion de tal manera a que me calcule si ya pasaron 24hs... la logica la tengo lo que no logro es la funcion de comparar...

Por ejemplo... el ultimo intento fallido es el 2012-01-09 09:06:00-03.. como calculo para saber si ya ha pasado 24hs y volver el campo habilitado a 1 nuevamente... :)
__________________
Ayudo con lo que puedo en el foro, y solo en el foro.. NO MENSAJES PRIVADOS.. NO EMAILS NI SKYPE u OTROS.

Antes de hacer un TOPICO piensa si puedes hallarlo en Google o en el Buscador del Foro...
  #4 (permalink)  
Antiguo 09/01/2012, 07:36
Avatar de linuxzero  
Fecha de Ingreso: noviembre-2011
Ubicación: Argentina
Mensajes: 778
Antigüedad: 13 años
Puntos: 160
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

usando los timestamp, para calcular que paso 24 horas seria asi:

Código PHP:
Ver original
  1. <?php
  2.  
  3. $horas24 = 60 * 60 * 24; //86400
  4.  
  5. return ($timestamp_now - $timestamp_ultimo_intento) > $horas24; // caso que la resta sea mayor es que 24 horas, entonces devuelve true, caso contrario false.
  6.  
  7. ?>

Seria algo asi
__________________
Si todo fuera tan sencillo como un symfony cc la vida seria más fácil.
http://phpnico.wordpress.com
  #5 (permalink)  
Antiguo 09/01/2012, 08:16
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

Algo así te puede servir
Código PHP:
Ver original
  1. <?php
  2. $datetime1 = new DateTime('2012-01-08 08:00:00');
  3. $datetime2 = new DateTime();
  4. $interval = $datetime1->diff($datetime2);
  5. if($interval->format('%a') >= 1){
  6.     echo 'quitar bloqueo';
  7. }
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #6 (permalink)  
Antiguo 09/01/2012, 11:00
Avatar de loncho_rojas
Colaborador
 
Fecha de Ingreso: octubre-2008
Ubicación: En el mejor lugar del mundo
Mensajes: 2.704
Antigüedad: 16 años, 1 mes
Puntos: 175
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

ok.. supongamos que en mi campo ULTIMOINTENTO que es un timestamp en la BD tengo este valor :

2012-01-09 13:43:00

me dicen que debo sacar una diferencia entre el ULTIMOINTENTO con el TIMESTAMP actual y compararlo para ver si es mayo o menor a un valor X que puede ser numero de horas o algo asi.. ok

Traer el dato guardado no tengo ningun drama.. pero como lo comparo con la fecha y hora actual de timestamp con PHP? o sea... si imprimo mi fila $rs['ultimointento'] obtengo 2012-01-09 13:43:00

pero no se si resultaria eso de restar las fechas, es decir, no se si matematicamente es posible restar (2012-02-09 13:43:00 menos 2012-01-09 13:43:00) y eso darme un resultado posible para generar mi comparacion...

Amigo abimaelrc gracias tambien por tu aporte... no es que no quiera pensar ni trabajar, pero no comprendo el script que me pasas, y no se si es aplicable ya que maneja logica de POO y no tengo armada ninguna clase que pueda servir con ese script...

Estoy buscando alternativas pero la verdad no logro aun ningun resultado :(
__________________
Ayudo con lo que puedo en el foro, y solo en el foro.. NO MENSAJES PRIVADOS.. NO EMAILS NI SKYPE u OTROS.

Antes de hacer un TOPICO piensa si puedes hallarlo en Google o en el Buscador del Foro...
  #7 (permalink)  
Antiguo 09/01/2012, 11:24
webankenovi
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

restalo con time();

si se produjo el ultimo intento guardas el time() y luego comparas restando si an pasado 24 horas o las que quieras

primero creas un campo en la tabla que quieras llamado intentos y otros time por ejemplo

cada fallo haces un update en la columna intentos y si a llegado a los 5 intentos guardas el 5 intento y el time() de ese momento

antes del login verifica si intentos es mayor o menor de 5 si es menor le dejes seguir normal si es igual a 5 compruebas el time() de ese intento y comparas con el que guardaste anteriormente en el ultimo intento y si es mayor a 24 horas le dejas seguir

Última edición por webankenovi; 09/01/2012 a las 11:37
  #8 (permalink)  
Antiguo 09/01/2012, 11:43
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

El ejemplo que te di está completo, es decir hace una diferencia de la hora actual contra la hora que haya colocado. Si te fieras en $datetime2 coloqué la fecha, lo único que tienes que hacer es colocar el timestamp que sostiene la variable que estés usando y hacer el calculo usando el método diff, luego en la condición verificas si ha pasado 1 día o más si es así entonces ya ha transcurrido más de 24 horas si no pues va a aparecer con 0.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #9 (permalink)  
Antiguo 09/01/2012, 12:07
Avatar de loncho_rojas
Colaborador
 
Fecha de Ingreso: octubre-2008
Ubicación: En el mejor lugar del mundo
Mensajes: 2.704
Antigüedad: 16 años, 1 mes
Puntos: 175
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

Cita:
Iniciado por abimaelrc Ver Mensaje
El ejemplo que te di está completo, es decir hace una diferencia de la hora actual contra la hora que haya colocado. Si te fieras en $datetime2 coloqué la fecha, lo único que tienes que hacer es colocar el timestamp que sostiene la variable que estés usando y hacer el calculo usando el método diff, luego en la condición verificas si ha pasado 1 día o más si es así entonces ya ha transcurrido más de 24 horas si no pues va a aparecer con 0.
Me parece muy bien explicado, la verdad no conocia la clase DateTime... con respecto a la clase que me pasas.. tengo un error de sintaxis justo en la linea del ECHO.. que podría ser?
__________________
Ayudo con lo que puedo en el foro, y solo en el foro.. NO MENSAJES PRIVADOS.. NO EMAILS NI SKYPE u OTROS.

Antes de hacer un TOPICO piensa si puedes hallarlo en Google o en el Buscador del Foro...
  #10 (permalink)  
Antiguo 09/01/2012, 16:30
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

A mí no me causa problemas, ¿qué te dice?
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #11 (permalink)  
Antiguo 10/01/2012, 05:44
Avatar de loncho_rojas
Colaborador
 
Fecha de Ingreso: octubre-2008
Ubicación: En el mejor lugar del mundo
Mensajes: 2.704
Antigüedad: 16 años, 1 mes
Puntos: 175
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

No se que habra podido ser, pero estuve leyendo el manual de php con la funcion DateTime y demas y he sacado lo productivo de él, muy similar a lo que me haz pasado como solucion.. funciona muy bien.. ahora solo resta acomodarlo a mi script de arriba a ver que tal funciona .. los estare comunicando
__________________
Ayudo con lo que puedo en el foro, y solo en el foro.. NO MENSAJES PRIVADOS.. NO EMAILS NI SKYPE u OTROS.

Antes de hacer un TOPICO piensa si puedes hallarlo en Google o en el Buscador del Foro...
  #12 (permalink)  
Antiguo 10/01/2012, 08:17
Avatar de loncho_rojas
Colaborador
 
Fecha de Ingreso: octubre-2008
Ubicación: En el mejor lugar del mundo
Mensajes: 2.704
Antigüedad: 16 años, 1 mes
Puntos: 175
Respuesta: Bloquear usuario por un tiempo determinado luego de intentos fallidos

bueno, lo hice asi...

esta es la estructura basica de mi BD.. no lo pongo todo para guardarme ciertos datos

Código SQL:
Ver original
  1. CREATE TABLE `usuarios` (
  2. `idcliente` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  3. `email` VARCHAR( 100 ) NOT NULL ,
  4. `pass` VARCHAR( 50 ) NOT NULL ,
  5. `verificacion` VARCHAR( 10 ) NOT NULL ,
  6. `ultimavisita` TIMESTAMP NOT NULL ,
  7. `ultimointento` TIMESTAMP NOT NULL ,
  8. `intentos` INT NOT NULL
  9. ) ENGINE = MYISAM ;


aqui el procesador PHP que recibe la clave y contraseña:

Código PHP:
<?php
//esto lo copie de algun post del foro
session_start(); // Se destruye cualquier 
session_unset(); // session anterior antes de 
session_destroy(); // comenzar con el scrip. Esto es opcional 

include("../conn/conect.php");

//ahora si el codigo
if($_POST){
            
            
$email $_POST["username"];
            
$clave $_POST["password"];
            
//$fecha= date("d-m-y H:i");
            
            //echo getdate();
            
unset($_POST); //Se destruye el array $_POST
            
            
if(preg_match("/^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$/"$email)){
                
                
$sql_login="SELECT * FROM usuarios WHERE email LIKE '".$email."'";        
                
$resultado_login=pg_query($sql_login)or die("Error query ".pg_last_error());
                
                if(
pg_num_rows($resultado_login) == 1){
                    
                    
$fila_usuario=pg_fetch_array($resultado_loginnullPGSQL_ASSOC);
                    
                    
//obtener fecha actual para compararlo con el ultimo intento
                    
$fecha getdate();
                    
$today=($fecha["year"]."-".$fecha["mon"]."-".$fecha["mday"]." ".$fecha["hours"].":".$fecha["minutes"].":".$fecha["seconds"]);
                    
//genero una resta de la fecha actual contra el ultimo intento guardado en la BD        
                    
$datetime1 = new DateTime($today);
                    
$datetime2 = new DateTime($fila_usuario['ultimointento']);
                    
$intervalo $datetime1->diff($datetime2);
                    
                        
                    
                     if(
$fila_usuario['intentos'] < 5){
                         
                         
                                     if(
$fila_usuario['pass']== $clave){
                                         
                                            
//validamos si la cuenta ya esta verificada 
                                            
if($fila_usuario["verificacion"]=="si")
                                            {
                                                
                                                
session_start();
                                                
$_SESSION["k_username"] = $fila_usuario["nombres"].", ".$fila_usuario["apellidos"];
                                                
$_SESSION["k_idcliente"] = $fila_usuario["idcliente"];
                                                
                                                
                                                
                                                
pg_query($conn2"UPDATE usuarios SET ultimavisita='NOW()', intentos='0' WHERE idcliente=".$fila_usuario['idcliente'])or die("Error query ".pg_last_error());
                                                
                                                
header("Location: ../clients/principal-clients.php");
                        
                                            }
//caso contrario, tiramos un mensaje de que aun no ha sido verificada la cuenta
                                            
else
                                            {
                                                echo 
"<h1>Su cuenta aun no ha sido verificada.</h1>";
                                                echo 
"<p>Si ya se ha registrado desde nuestro sitio Web:</p>";
                                                echo 
"<ul>
                                                        <li>Por favor, revise su correo electrónico.</li>
                                                        <li>Siga las instrucciones que le hemos enviado.</li>
                                                        <li>Inicie Sesi&oacute;n.</li>
                                                      </ul>"
;
                                                echo 
"<p>Caso contrario, puede <a href='registro.php'>registrarse</a> para acceder a los servicios</p>";
                                            }
                                         
                                     
                                     }else{
                                         
pg_query($conn2"UPDATE usuarios SET ultimointento='NOW()', intentos=intentos+1 WHERE idcliente=".$fila_usuario['idcliente'])or die("Error query ".pg_last_error());
                                         
                                         echo 
"<p style='font-size:14px; color:#FF0000;'>El password no es valido!!</p>";
                                         
                                         
                                         
$cn pg_query("SELECT * FROM usuarios WHERE idcliente=".$fila_usuario['idcliente'])or die("Error query ".pg_last_error());
                                         
$rspg_fetch_array($cn);
                                        
                                         echo 
"<p>Recuerde que s&oacute;lo posee <strong>5 intentos</strong> para ingresar a su cuenta correctamente.</p>";
                                         echo 
"<p>Este es su intento N&deg;: <span style='font-size:15px;'>".$rs['intentos']."</span></p>";
            
                                     }
//fin verificacion de correcto logueo a traves del password
                         

                         
}else{
                             
                             
//primero comparamos si y han pasado mas de 24hs desde el ultimo intento fallido
                             
if($intervalo->format('%a')>1){
                                    
pg_query($conn2"UPDATE usuarios SET intentos='1' WHERE idcliente=".$fila_usuario['idcliente'])or die("Error query ".pg_last_error());    
                                    echo 
"<h2>Hemos desbloqueado su cuenta nuevamente</h2>";
                                    echo 
"<p>Han pasado 24hs. del bloqueo de su cuenta. Por favor, ingrese nuevamente el usuario y clave de ingresos</p>";
                                }else{
                                    
//caso contrario le decimos que la cuenta aun esta bloqueada
                                    
header("Location: ../pages/cuenta-bloqueada.php");
                                }
                         }
//fin verificacion de numero de intentos
                    
                     
                    
                
}else{
                    echo 
"<p>La direccion de email ingresada no esta registrada</p>";
                    
                }
                
                
            
            }else{
                echo 
"<p>Ingrese una direccion de email valida</p>";
            }
            
            
            
        }else{
            
            
header("Location: ../index.php");
        }



?>
Bueno, yo uso postgres en vez de MySql.. pero es similar... en las funciones predeterminadas de php en vez de pg se utiliza el mysql.. o sea en pg_query o pg_fetch_array se lo cambian nomas a mysql_query o mysql_fetch_array... ya lo van a ir pillando.. seguro tiene alguno que otro defectito, pero si lo quieren mejorar bienvenido sea

espero les sirva
__________________
Ayudo con lo que puedo en el foro, y solo en el foro.. NO MENSAJES PRIVADOS.. NO EMAILS NI SKYPE u OTROS.

Antes de hacer un TOPICO piensa si puedes hallarlo en Google o en el Buscador del Foro...

Etiquetas: bloquear, determinado, intentos, mysql, registro, sql, tabla, usuarios
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 10:17.