PHP 7 – Login y cifrado de contraseña con hash mediante PDO

PDO es una nueva forma que ha implementado PHP en su versión 7 que te permite conectarte a múltiples gestores de bases de datos sin tener que alterar demasiado el código como suele pasar con MySQLi.

En este ejemplo voy a explicar:

– cómo he dado de alta un usuario en una base de datos cifrando su contraseña mediante PDO con hash

– cómo he comprobado la clave del usuario al iniciar sesión mediante PDO

– como hacer una consulta SQL con PDO partiendo de que el usuario ya existe

Antes de nada decir que este es un ejemplo muy sencillo de login y hay muchas formas de hacer esto. Lo ideal sería que una vez entiendas este tutorial le implementes las sesiones de PHP que eso lo hare más adelante en otro tutorial.

Dar de alta un usuario y cifrar su contraseña

En phpMyAdmin he creado una base de datos llamada usuarios y dentro una tabla llamada registros a la que le he añadido los siguientes campos:

Id, tipo, email, nombre, contraseña, sexo

NOTA: el campo “tipo” es para decir si es persona o empresa (me ha dado por hacerlo así).

Ahora creo un fichero php llamado conexion.php que será el encargado de realizar la conexión a la base de datos y donde creare un objeto PDO que será el que usaré para realizar todas las funciones que necesite.


<?php  
//configuracion de la conexion
$servidor = 'localhost';
$base_datos = 'usuarios';
$usuario = 'root';
$clave = '';

//establezco la conexion con PDO en este caso para MySQL
$conexion = new PDO("mysql:host=$servidor; dbname=$base_datos", $usuario, $clave);
	
//aplico el español	
$conexion->exec("SET CHARACTER SET utf8");
?>

Lo que hay que tener en cuenta es que en la variable $conexion uno de los campos que contiene es mysql es en ese punto donde determinas que gestor de base de datos quieres usar, en mi caso yo he usado mysql.

El siguiente paso es tener un formulario de registro donde tengamos todos los campos a añadir yo he creado un fichero llamado registro.html donde voy a mostrar solo la parte del formulario, el CSS ya depende de vosotros.


<form action="formulario.php" method="post">

<input type="radio" value="persona" id="persona" name="tipo" checked/>
<label for="persona" class="radio" chec>Persona</label>

<input type="radio" value="empresa" id="empresa" name="tipo" />
<label for="empresa" class="radio">Empresa</label>

<label id="icon" for="email"><i class="icon-envelope "></i></label>
<input type="text" name="email" id="email" placeholder="Email" required/>

<label id="icon" for="nombre"><i class="icon-user"></i></label>
<input type="text" name="nombre" id="nombre" placeholder="Nombre" required/>

<label id="icon" for="clave"><i class="icon-shield"></i></label>
<input type="password" name="clave" id="clave" placeholder="Contraseña" required/>

<input type="radio" value="hombre" id="hombre" name="sexo" checked/>
<label for="hombre" class="radio" chec>Hombre</label>

<input type="radio" value="mujer" id="mujer" name="sexo" />
<label for="mujer" class="radio">Mujer</label>

<p>Si te registras accedes a verderme tu alma bro.</p>

<input type="submit" value="registro" class="button">

</form>

Esos son los campos que he usado en el formulario, ahora tu solo has de aplicarle el css. Esta parte está a punto de finalizar, ahora vamos a mirar el siguiente fichero que es el que aparece al comienzo del formulario, el fichero formulario.php que lo que va a hacer es coger todos los datos del formulario, cifrar la contraseña e introducirlo todo en la base de datos.


<?php  
/*
obligo a este fichero
a usar mis datos de
acceso a la base de datos
*/
require 'conexion.php';

//antes de nada obtengo la contraseña y la cifro para insertarla
$clave = $_POST['clave'];

//y ahora cifro la clave usando un hash
$clave_cifrada = password_hash($clave, PASSWORD_DEFAULT, array("cost"=>15));

/*
el "cost" lo que indica es la fuerza con la que se cifra la clave
a mayor fuerza mas tiempo de carga requiere la página por eso es
importante que busques un equilibrio
*/

/*
compruebo que la conexion es correcta
y de ser asi hago el insert
*/
if ($conexion == true) {
	
 //preparo el insert...
 $insert = $conexion->prepare("INSERT INTO registros (tipo, email, nombre, contraseña,sexo) VALUES (:tipo, :email, :nombre, :clave, :sexo)");

 //asocio los campos del insert a los campos del formulario
 $insert->bindParam(':tipo', $_POST['tipo']);
 $insert->bindParam(':email', $_POST['email']);
 $insert->bindParam(':nombre', $_POST['nombre']);
 $insert->bindParam(':clave', $clave_cifrada);
 $insert->bindParam(':sexo', $_POST['sexo']);

 //si no he echo el imbecil y todo esta correcto ejecuto lo anterior
 $insert->execute();

 //cierro la conexion
 $conexion = null;

 //redirijo a otro archivo php
 header('Location: listado.php');
} else {
 echo "Algo ha fallado bro";
}
?>

En este bloque de código cuando el usuario es registrado lo mando a otra página donde hago una consulta SQL de todos los usuarios registrados, pero esa parte la voy a mostrar más adelante. Lo que viene siendo este punto ya ha terminado, así que voy a resumir lo que he hecho.

1.- He creado un fichero de conexión con los datos de acceso a mi base de datos y le especificado que gestor de base de datos quiero utilizar gracias a PDO.

2.- He creado un formulario en HTML que lo he asociado a otro fichero php.

3.- en el fichero php he obtenido la clave, la he cifrado, he obtenido los datos del resto del formulario y los he añadido a la base de datos, el resultado tiene que ser algo como esto:

clave cifrada PDO

Iniciar sesión con una clave cifrada mediante PDO

En este paso lo que voy a mostrar es como comprobar una clave cifrada y almacenada en la base de datos y en caso de que sea correcto que haga lo que tenga que hacer, en este caso que envíe a otra página donde se hará una consulta SQL muy sencilla.

Para ello creo un fichero HTML llamado login.html en el tengo un formulario HTML donde llamo a un fichero php. Como en el ejemplo anterior voy a mostrar el código del formulario, el CSS depende de vosotros.


<form action="comprueba_login.php" method="post">

<label id="icon" for="nombre"></label>
<input type="text" name="nombre" id="nombre" placeholder="Nombre" required/>

<label id="icon" for="clave"></label>
<input type="password" name="clave" id="clave" placeholder="Contraseña" required/>

<input type="submit" value="Acceder" class="button">

</form>

Como se puede ver en el código, el formulario llama a un fichero llamado comprueba_login.php ese fichero lo que va hacer es recibir el usuario y contraseña (sin cifrar) y mediante un hash aleatorio creado por PHP va a comparar la clave introducida con la cifrada y dirá si el usuario existe o no en la base de datos.


<?php
/*
obligo a este fichero
a usar mis datos de
acceso a la base de datos
*/
require 'conexion.php';

try {
 //obtengo los datos del formulario...
 $nombre=htmlentities(addslashes($_POST['nombre']));
 $clave=htmlentities(addslashes($_POST['clave']));

 //variable auxiliar para comprobar que el usuario existe (una forma de hacerlo)
 $contador = 0;

 //almaceno la consulta SQL
 $sql = "SELECT * FROM registros WHERE nombre = :nombre";

 //preparo la consulta SQL
 $resultado=$conexion->prepare($sql);

 //ejecuto la consulta SQL
 $resultado->execute(array(":nombre"=>$nombre));

 //almaceno el resultado en un array asociativo y lo recorro
 while($registro=$resultado->fetch(PDO::FETCH_ASSOC)) {
  /*
   el metodo password_verify tiene 2 parametros
   el 1º es la clave que se envia por el formulario
   el 2º es el hash de la clave que almacena en la BBDD
   este metodo se utiliza para comprobar si la clave
   coincide o no
  */
  if(password_verify($clave, $registro['contraseña'])) {
   /*
    aqui es donde ya harias lo que tu quieras, puedes
    crear una sesión, imprimir html, etc... yo voy a
    incrementar la variable contador
   */
   $contador++;
  }
 }

 /*
  si el while ha tenido exito evitendemente hara lo que le pidas
  en este caso yo voy a comprobar la variable contador, si es verdad
  que ha encontrado un usuario con la clave correcta y lo ha incrementado
  entonces existe en caso contrario no existe
 */
 if ($contador>0) {
  echo "el usuario existe";
 } else {
  echo "el usuario no existe";
 }

 //cierro la conexion
 $conexion = null;
} catch(Exception $e) {
   die($e->getMessage());
}
?>

Esta parte ya está finalizada como en el anterior punto voy a resumir lo que ha pasado:

1.- Se parte de un formulario HTML donde introduces los datos.

2.- Se compara la clave introducida por el usuario con la cifrada en la base de datos mediante un hash.

3.- Si todo ha sido correcto muestra un mensaje y si no es así muestra otro mensaje.

Generar consultas HTML con PDO

En el primer punto del tutorial se ha visto que cuando un usuario se registraba se le mostraba una tabla con todos los usuarios registrados y su clave cifrada pues en este punto eso es lo que se va a ver, como generar HTML mediante PHP.

Para ello me he creado un fichero llamado listado.php que contiene el siguiente código:


<?php
/*
obligo a este fichero
a usar mis datos de
acceso a la base de datos
*/
require 'conexion.php';

//preparo una consulta SQL
$sql = "SELECT * FROM registros";

//almaceno el restulado
$resultado = $conexion->query($sql);
?>

//genero la tabla con html
<table border="solid">
 <tr>
  <td>Id</td>
  <td>Tipo</td>
  <td>Email</td>
  <td>Nombre</td>
  <td>Contraseña</td>
  <td>Sexo</td>
 </tr>

<?php
//recorro toda la consulta
foreach($resultado as $fila) {
 echo "<tr>";
 echo "<td>".$fila['id']."</td>";
 echo "<td>".$fila['tipo']."</td>";
 echo "<td>".$fila['email']."</td>";
 echo "<td>".$fila['nombre']."</td>";
 echo "<td>".$fila['contraseña']."</td>";
 echo "<td>".$fila['sexo']."</td>";
 echo "</tr>";
}
?>
//cierro la tabla
</table>

Y es todo, ya tienes un sistema de login escalable y con el método actualmente más fuerte de cifrado que contiene PHP. En un próximo tutorial hare este mismo ejemplo pero implementando sesiones.

¡¡no olvides compartir!!

anterior
siguiente

© Copyright - Antonio Páez- Programación Web -