elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Desarrollo Web
| | |-+  PHP (Moderador: #!drvy)
| | | |-+  [Resuelto]Login solo en PHP
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [Resuelto]Login solo en PHP  (Leído 3,443 veces)
danny920825

Desconectado Desconectado

Mensajes: 175


Ver Perfil WWW
[Resuelto]Login solo en PHP
« en: 4 Enero 2017, 17:59 pm »

Hola a todos nuevamente. Me gustaría traerles un pequeño login que hice en PHP sin JQuery ni nada de eso. Solo PHP y HTML. Quisiera que me digan qué les parece el código y si hay formas de que usando solo PHP, no salga en el código fuente de la página la contraseña o que me digan cómo darle más seguridad al formulario y esas cosas. Sin dilatarnos más, veamos los 2 archivos:

Login.php
Código
  1. <?php
  2. if (isset($_SESSION['userid']))
  3. {
  4. header("location:index.php");
  5.  
  6. }
  7. else
  8. {
  9.  
  10. ?>
  11. <html>
  12. <head>
  13. <title>Login de Usuario</title>
  14. </head>
  15. <link rel="stylesheet" href="css/login.css" type="text/css" />
  16. <body>
  17. <br /><br /><br />
  18. <center>
  19. <h2>Ingrese sus datos para acceder al sistema</h2>
  20. <form action="logon.php" method="post" name="form">
  21. <table border='0' bgcolor="">
  22. <tr>
  23. <td><b>
  24.  <p align="right">Usuario</p></b></td>
  25. <td align="center"><input type="text" name="user"></td>
  26. </tr>
  27. <tr>
  28. <td><b>
  29. <p align="right">Contrase&ntilde;a</p>
  30. </b></td>
  31. <td align="center"><input type="password" name="pass"></td>
  32. </tr>
  33. <tr align="center">
  34. <td>
  35. </td>
  36. <td>
  37. <input type="submit" value="enviar"><input type="reset" value="limpiar" name="limpiar">
  38. </td>
  39. </tr>
  40. <?php
  41. if (isset($_SESSION['error']))
  42. {
  43. $mensaje=$_SESSION['error'];
  44. echo("<tr align='right'><td colspan='2'>$mensaje</td></tr>");
  45. }
  46.  
  47. ?>
  48. </table>
  49. </form>
  50. </center>
  51. <center><b><a href='guest.php'>Entrar como invitado</a></b></center>
  52.  
  53. <?php
  54. }
  55. ?>
  56. </body>
  57. </html>
  58.  
  59.  
La idea es que si ya tienes un login realizado no te deje acceder a esa página, sino que te redireccione al index.php.

Ahora el logon.php que es quien gestiona los usuarios con la BD
Código
  1. <?php
  2. //recuperacion de variables
  3. session_start();
  4. $usuario=$_REQUEST['user'];
  5. $password=$_REQUEST['pass'];
  6. $mensaje="Usuario o Contrase&ntilde;a incorrectos";
  7.  
  8. //base de datos
  9. $conexion=mysqli_connect("localhost", "usuario", "contraseña") or die (mysqli_error($conexion));
  10. $bd="trabajo";
  11. $tabla="usuarios";
  12. mysqli_select_db($conexion, $bd)or die (mysqli_error($conexion));
  13. //$cifrar=base64_encode($password);
  14.  
  15. //seleccion del usuario
  16. $registro=mysqli_query($conexion, "select * from $tabla where (usuario='$usuario')") or die ("Usuario desconocido");
  17. {
  18. if ($reg=mysqli_fetch_array($registro))
  19. {
  20. if ($password==$reg['password'])
  21. {
  22. $_SESSION['userid']=$_REQUEST['user'];
  23. $_SESSION[nivel]= $reg[nivel];
  24. mysqli_close($conexion);
  25. header("location:index.php");
  26. }
  27. else
  28. {
  29. $_SESSION['error']=$mensaje;
  30. echo ("error");
  31. mysqli_close($conexion);
  32. header("location:login.php");
  33. }
  34. }
  35. else
  36. {
  37. $_SESSION['error']=$mensaje;
  38. echo ("error");
  39. mysqli_close($conexion);
  40. header("location:login.php");
  41. }
  42. }
  43. ?>
  44.  

Y así estamos listos. Yo recupero el nivel porque así puedo establecer permisos a los usuarios dependiendo de su nivel. Y en el login solo necesitamos recuperar las variables de sesion así

Código
  1. session_start();
  2. if (isset($_SESSION['userid']))
  3. {
  4.  
  5. ?>
  6. Aqui ponemos todo el index.php si el usuario se logueó bien. Si no abrimos php de nuevo escribimos
  7. <?php
  8. }
  9. else
  10. {
  11. header("location:login.php");
  12. }
  13. ?>
  14. </body>
  15. </html>
  16.  
  17.  
  18.  


« Última modificación: 5 Enero 2017, 22:02 pm por danny920825 » En línea

"Los que reniegan de Dios es por desesperación de no encontrarlo".
   Miguel de Unamuno
engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Login solo en PHP
« Respuesta #1 en: 4 Enero 2017, 18:17 pm »

el login en lineas generales está bien, aunque debería tener algunas validaciones adicionales...

no uses $_REQUEST, usa ya sea $_POST o el método especifico

las lineas 30 y 38 te causarán errores
según documentación
http://php.net/manual/es/function.header.php



si usas header, no usas nunca echo antes... y si es para redirect, tampoco es necesario despues porque no se verá (excepto el caso de una api que use no redirect)


la contraseña está almacenada de forma insegura... base64 no es cifrar, es codificar, y las contraseñas deben estar almacenadas en forma de hash+salt ara evitar problemas.... la forma más simple de eso es usar password_hash para guardar y password_verify para comparar



En línea

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
#!drvy
Moderador
***
Desconectado Desconectado

Mensajes: 5.855



Ver Perfil WWW
Re: Login solo en PHP
« Respuesta #2 en: 4 Enero 2017, 18:47 pm »

Citar
Código
  1. $cifrar=base64_encode($password);

Eso no es cifrar. Eso es encoding o dicho en español: Codificación. Si lo que quieres es convertir la contraseña en un hash tendrás que usar un algoritmo de un solo camino. Preferiblemente bcrypt o scrypt.

https://es.wikipedia.org/wiki/Codificaci%C3%B3n_de_caracteres
https://es.wikipedia.org/wiki/Funci%C3%B3n_hash
https://en.wikipedia.org/wiki/Bcrypt

Código
  1. $salt = 'hDvTFAsHtrB3oagFNggnUa';
  2. $cifrar = crypt($password, '$2a$12$' . $salt);



Citar
Código
  1. $usuario=$_REQUEST['user'];
  2. $password=$_REQUEST['pass'];
  3. ....
  4.  
  5. $registro=mysqli_query($conexion, "select * from $tabla where (usuario='$usuario')")
  6.  

Regla numero #1 del desarrollador: Nunca te fíes de lo que te manda un usuario.

Ese código es vulnerable a SQLi (inyección sql). Puedes utilizar sentencias preparadas para evitar sqli. Por otro lado, evita usar $REQUEST. Solo quieres obtener datos que se envían por POST (tu formulario HTML). REQUEST incluye GET, POST y COOKIES.. no te interesa, mas bien perjudica.

Código
  1. $usuario=$_POST['user'];
  2. $password=$_POST['pass'];
  3. $salt = 'hDvTFAsHtrB3oagFNggnUa';
  4.  
  5.  
  6. $cifrar = crypt($password, '$2a$12$' . $salt);
  7.  
  8. $query = "select * from {$tabla} where (usuario=?)";
  9.  
  10. $stmt = mysqli_prepare($conexion, $query);
  11. mysqli_stmt_bind_param($stmt, 's', $usuario);
  12.  
  13. ....

http://php.net/manual/es/mysqli.quickstart.prepared-statements.php



Citar
Código
  1. if ($password==$reg['password'])

No uses == para comparar cadenas de texto. Puedes tener problemas porque PHP convierte a los valores a semejanza. Para que me entiendas:

Código
  1. if(0=='hola'){ echo "hola"; } // Imprime hola
  2. if(0==='hola'){ echo "hola"; } // No imprime nada (no cumple)

Usa siempre === para comparar strings. Tampoco veo que estés comparando la contraseña hasheada.. comparas directamente dos cadenas de texto.

Código
  1. if($cifrar===$reg['password'])

Y ya que vamos a utilizar bcrypt, mejor:

Código
  1. if(hash_equals($cifrar, $reg['password']))

http://php.net/manual/es/function.crypt.php
http://php.net/manual/es/function.hash-equals.php



Citar
Código
  1. $_SESSION['userid']=$_REQUEST['user'];

Primera regla. No nos fiemos. El usuario podría suplantar su "user" por el tuyo. Saca el userid siempre de la base de datos, de la entrada que corresponde a su usuario.



Citar
Código
  1. echo ("error");
  2. mysqli_close($conexion);
  3. header("location:login.php");

echo no es una función. No la uses como tal (funciona pero esta mal). Utilizar header() después de imprimir algo suele tirar errores. Recuerda que en protocolo HTTP los headers siempre van antes que el contenido. En algunos navegadores, no pasar la url completa del sitio puede generar errores de redireccionamiento.

Código
  1. mysqli_close($conexion);
  2. header('Location: http://misitio.com/login.php');
  3. echo 'Error';

Saludos
« Última modificación: 4 Enero 2017, 18:56 pm por #!drvy » En línea

danny920825

Desconectado Desconectado

Mensajes: 175


Ver Perfil WWW
Re: Login solo en PHP
« Respuesta #3 en: 4 Enero 2017, 19:01 pm »

Gracias por su pronta respuesta. Realmente el echo es infuncional, solo que copie el código de una salva anterior porque el original está en casa.
Código
  1.    echo ("error");
  2.    mysqli_close($conexion);
  3.    header("location:login.php");

Ya estoy viendo la documentacion que me dieron sobre el hash y salt y la cifrado en un solo sentido, así como el password verify y password hash. Para la comunicación con la BD no hay forma de encriptarla? que no se vea la contraseña en el código fuente?

y esto no lo entiendo, lo podrían explicar?
Código
  1. $stmt = mysqli_prepare($conexion, $query);
  2. mysqli_stmt_bind_param($stmt, 's', $usuario);
  3.  

Gracias por adelantado
En línea

"Los que reniegan de Dios es por desesperación de no encontrarlo".
   Miguel de Unamuno
#!drvy
Moderador
***
Desconectado Desconectado

Mensajes: 5.855



Ver Perfil WWW
Re: Login solo en PHP
« Respuesta #4 en: 4 Enero 2017, 19:12 pm »

Citar
Para la comunicación con la BD no hay forma de encriptarla? que no se vea la contraseña en el código fuente?

Podrías ofuscarla y parecidos pero generalmente a fin de cuentas, no. Se asume que solo el administrador tiene acceso a dicho código.

Citar
y esto no lo entiendo, lo podrían explicar?

mysqli_prepare, prepara una sentencia para que se le asignen parámetros y posteriormente sea ejecutada. Con las sentencias preparadas, en vez de enviar todos los datos en la query, envías primero la query y luego las variables. De este modo evitas que una variable puede escapar de su entorno y modifique la query.

mysqli_stmt_bind_param, asigna un parámetro a una sentencia. En este caso, lo asignamos a $stmt que es nuestra sentencia. Le decimos que la próxima variable (el ? en la query) tipo string debe contener el valor de la variable $usuario.

En reducidas cuentas, esto:

Código
  1. SELECT * FROM {$tabla} WHERE (usuario=?)

Pasa a ser esto:
Código
  1. SELECT * FROM {$tabla} WHERE (usuario='donpepito')

Pero de forma segura.


mysqli_stmt_execute lo que hace es ejecutar la sentencia y devolver un identificador para su posterior uso. Lo tienes todo bastante explicado en el enlace que te deje:

http://php.net/manual/es/mysqli.quickstart.prepared-statements.php

Saludos
En línea

danny920825

Desconectado Desconectado

Mensajes: 175


Ver Perfil WWW
Re: Login solo en PHP
« Respuesta #5 en: 4 Enero 2017, 19:17 pm »

Gracias por la ayuda, no habia visto ese enlace. Ya estoy estudiando. Si tengo otras dudas vuelvo. Es bueno saber que hay personas que responden en tiempo y que están dispuestas a ayudar.
En línea

"Los que reniegan de Dios es por desesperación de no encontrarlo".
   Miguel de Unamuno
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[Resuelto] ¿Actualizar sólo el kernel o todo el S.O?
GNU/Linux
CodeJiyu 7 4,323 Último mensaje 5 Mayo 2014, 21:57 pm
por CodeJiyu
[resuelto] foreach solo devuelve un valor? habiendo 20
PHP
venadHD 4 2,921 Último mensaje 20 Julio 2015, 11:05 am
por venadHD
[Resuelto] problema con login en laravel 5.1 « 1 2 »
PHP
bengy 10 5,486 Último mensaje 14 Octubre 2015, 19:31 pm
por EFEX
chat que solo funciona con login en alguna pagina
Hacking
tincopasan 1 3,034 Último mensaje 26 Abril 2017, 03:17 am
por lorenso369
[Resuelto] Check Login y redirigir en función de un mail
PHP
bgnumis 2 2,200 Último mensaje 27 Agosto 2019, 12:13 pm
por #!drvy
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines