Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > PHP
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-01-2010
hibero hibero is offline
Miembro
 
Registrado: nov 2003
Posts: 104
Poder: 21
hibero Va por buen camino
validar usuarios de forma correcta

pretendo que los usuarios se validen antes de entrar a mi sitio web. Los pares usuario/contraseña estarán almacenados en un tabla llamada usuarios dentro de una base de datos MySQL.

Código SQL [-]
  Create table usuarios(
     usuario varchar(20) not null primary key,
     passwd varchar(20) not null,
  );

tendré 3 ficheros

login.php : contendrá el formulario html donde se introducirá el usuario y la contraseña. Al hacer clic sobre el boton se enviará el formulario utilizando POST al script php autenticacion

Código PHP:
<form action="autenticacion.php" method="POST">
   
usuario:<input name="usuario" size="25" value=""/>
   
Contraseña:<input name="passwd" size="25" type="password"/>
   <
input type="submit" value="Inicio de sesión"/>
</
form
autenticacion.php: en este script se comprueba si el par usuario/contraseña suminisgtrado por el usuario coinciden con los almacenados en la base de datos

Código PHP:

  
if (login($_POST["usuario"],$_POST["passwd"])==1){
 
//Si coninciden usuario y congtraseña
    
session_start(); //iniciamos la sesion
    
$_SESSION["logeado"]=1//creamos una variable logeado=1 (1)
    
$_SESSION["usuario"]=$_POST["usuario"]; 
/*almaceno el usuario como variable de sesion para utilizarlo luego en mi aplicacion*/
    
header ("Location: index.php"); //todo es correcto estoy validado abro mi aplicacion web
:cool:  }
   else {
     
//si no existe se va a login.php
     
header("Location: login.php");
   }

/*esta funcion devuelve 1 si el par usuario/contraseña coinciden con los almacenados en la base de datos. Utilizo PDO para conectar con la base de datos. Además uso una consulta paramétrica para evitar SQLInjection
*/
  
function login($usuario,$passwd){
     
/*asignar valores pertinentes al crear el objeto PDO en mi caso prueba*/ 
     
$db = new PDO("mysql:host=localhost;dbname=prueba",'prueba','prueba');
     
$q $db->prepare("SELECT passwd from usuarios where usuario=:usuario");
     
$q->bindParam(':usuario',$usuario);
     
$q->execute();
     
$row $q->fetch(PDO::FETCH_ASSOC);
     if (
$row["passwd"]=="" || $row["passwd"]!=$passwd){
         return 
0// usuario/contraseña incorrecta
     
}
         else return 
1// usuario/contraseña correcta
     
$db=null;
  } 
(1) la variable logeado por motivos de seguridad debe reemplazar por una variable con un nombre más complicado por ejemplo "123AWETRT323esdaqwe" pero para no liarla mas usare "logeado"

seguridad.php: para evitar que alguien pueda ejecutar mi aplicacion(index.php) sin previamente haberse validado se incluirá seguridad php al principio de index.php de forma que sea lo primero que se ejecute

Código PHP:
<?php
    session_start
(); //inicio sesion

    
if ($_SESSION["logeado"] !=1) { //no estoy logeado debo logearme primero
       
header("Location: login.php");
       exit();
    }
      
//en caso contrario estoy logeado y puedo continuar con la aplicacion
?>
En todos los ficheros de mi aplicacion tendrán una primera linea como la siguiente para comprobar la seguridad

Código PHP:
   <?php  include("seguridad.php");   ?>
Esta forma de asegurar una aplicación la he encontrado googleando por ahi.

¿Qué se puede mejorar?
¿Qúe incluiriais?
¿Hay una forma de permitir sólamente 3 intentos?. Se me ocurre que agregando un nuevo campo en la base de datos numfallos, fecha,hora y que desde que se llegue a un número de fallos predeterminado que se bloquee durante un periodo de tiempo determinado desde fecha hora el usuario podría ser una mejora para eviar que alguien utilice un programa para hacer tropocientos intentos
¿es suficiente el uso de una consulta parametrica para evitar SQLInjection?

salu2 y gracias
Responder Con Cita
  #2  
Antiguo 04-01-2010
Avatar de Julián
Julián Julián is offline
Merodeador
 
Registrado: may 2003
Ubicación: en mi casa
Posts: 2.019
Poder: 10
Julián Va por buen camino
Jau!

Cita:
Empezado por hibero Ver Mensaje
¿es suficiente el uso de una consulta parametrica para evitar SQLInjection?
Pues no lo sé por que no las uso ni creo que lo vaya a hacer en el futuro, pero sin saberlo, me apostaría mi pijama de Chuck Norris a que no.

Debes comprobar que los valores recibidos en $_GET son válidos y no contienen cosas raras como código que pueda servir para hacer sql injecting o ataques xss. Es decir, antes de ejecutar el SELECT nos aseguramos de que las variables usuario y password contienen unicamente letras y dígitos, por ejemplo, y que no tengan caracteres como <,#,?,",', etc.
Para esto lo mejor sería usar un script de probada eficacia como Kses o PHPIDS.

Cita:
Empezado por hibero Ver Mensaje
¿Qué se puede mejorar?
La lógica que usas es "si el user no está autentificado no lo dejo entrar". Creo que sería mejor "Le dejo entrar si está autentificado". Es decir, que la opción por omisión debería ser no dejar entrar, pues si de alguna forma alguien consigue anular lo que hubiera en seguridad.php, por ejemplo sustituyendo dicho archivo no podría ir a ningún sitio. No se si este punto me ha quedado claro.

Cita:
Empezado por hibero Ver Mensaje
¿Qúe incluiriais?
El funcionamiento de seguridad.php debería ser el siguiente:
session_start;
if ($autentificado)
include('user.php');
else
include(login.php);

Teniendo en user.php el típico código que pone "hola fulanito" con los enlaces o botones para cerrar sesión, ver perfil, etc. Y en login.php el form con los inputs para user y password y si acaso otro botón o enlace para "recordar contraseña"

Ademas de eso en cada página, despues del seguridad.php deberias permitir unas cosas u otras en función de los derechos de acceso del uaurio, para lo cual deberías disponer de un sistema de permisos, con usuarios, roles, grupos, etc.

Lo del nombre de la variable logueado no le veo mucho sentido. En mis scripts dicha variable es booleana. Claro, que un usuario, además de poder tener true o false en "logueado" tambien tiene otra variable "userlevel" que le permite mas o menos privilegios. O sea, que un user con "logueado==true" cuyo userlevel sea el "level por omisión" es practicamente un "invitado" y poco puede hacer hasta que no se le hayan otorgado derechos de acceso a alguna parte o adjudicado algún rol o adscrito a algún grupo.

Cita:
Empezado por hibero Ver Mensaje
¿Hay una forma de permitir sólamente 3 intentos?. Se me ocurre que agregando un nuevo campo en la base de datos numfallos, fecha,hora y que desde que se llegue a un número de fallos predeterminado que se bloquee durante un periodo de tiempo determinado desde fecha hora el usuario podría ser una mejora para eviar que alguien utilice un programa para hacer tropocientos intentos
Lo de los intentos y el ampliar el tiempo entre ellos me parece cosa obligada y yo lo que hago es guardar los intentos asociados a la dirección IP, la cual, puedo llegar a meter en un filtro si hace falta.



Gueno, menudo rollo he largao, XDD
__________________
"la única iglesia que ilumina es la que arde"
Anonimo

Última edición por Julián fecha: 04-01-2010 a las 13:27:35.
Responder Con Cita
  #3  
Antiguo 04-01-2010
hibero hibero is offline
Miembro
 
Registrado: nov 2003
Posts: 104
Poder: 21
hibero Va por buen camino
Se que utilizar paràmetros en las consultas no soluciona todo (puede ser la constumbre de utilizarlas en delphi, "la cabra tira al monte"), pero sin tan solo se encaerga de asignar el tipo de datos correctos, pondrá más dificil . Además como comentas hay que revisar todas las variables que me pasen tanto por GET como por POST (no hay que fiarse nunca de un usuario). No conocía las librerias que mencionas pero voy a probarlas y supongo que acabarlas integrando en todo el proyecto.
el fichero seguridad.php está pensado para que en cada fichero php del proyecto incluir nada más empezar un include('seguridad.php'); de forma
que se comprueba la seguridad con solo incluir este include.
lo del nombre de la variable, es que lo lei por ahí,decidí incluirlo para ver si añgien me lo aclaraba.
En cuanto a limitar el acceso desde una dirección ip, me parece buena idea, pero que pasa si bloqueas un usurio que te entra desde la ip tal,¿No estarías bloqueando a todos los usuarios que están tras el mismo router ya que todos salen con la misma ip?

De rollo nada me has dado bastantes ideas,

salu2
Responder Con Cita
  #4  
Antiguo 04-01-2010
hibero hibero is offline
Miembro
 
Registrado: nov 2003
Posts: 104
Poder: 21
hibero Va por buen camino
se me acaba de ocurrir otra posible mejora, almacenar la passwd encriptada en la base de datos. Podría utilizar la funcion md5 de php

http://php.net/manual/en/function.md5.php

Salu2
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Pronunciación correcta. marcoszorrilla La Taberna 1 12-11-2008 22:38:25
Cual es la forma correcta de llamar y ejecutar un ProcAlmacenado en IB6 y Delphi 7??? Saltamontes Firebird e Interbase 5 11-07-2007 18:05:19
Cómo utilizar consultas con DISTINCT de forma correcta dec MySQL 9 19-09-2006 18:50:47
Cual es la Forma Correcta de Guardar Texto en un IbDataset con TcpServer???? AGAG4 Varios 0 10-12-2004 23:14:41
Forma correcta de emigrar base de datos.. ronimaxh Firebird e Interbase 5 08-04-2004 00:34:38


La franja horaria es GMT +2. Ahora son las 19:44:56.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi