viernes, 12 de julio de 2019

Login PHP y MySQL - contraseña encriptada

Base de datos

Creamos una base de datos (blog) y una tabla para almacenar el usuario y otra tabla relacionada llamada tipos_usuario cada uno con sus respectivos campos, entre ellos a la clave (en este caso se puede emplear MySQL o MariaBD).

-- -----------------------------------------------------
-- Tabla tipos_usuario
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS tipos_usuario (
  id INT NOT NULL AUTO_INCREMENT,
  nombre VARCHAR(30) NOT NULL,
  descripcion TEXT NULL,
  PRIMARY KEY (id)
)ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

-- -----------------------------------------------------
-- Tabla usuarios
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS usuarios (
  id INT NOT NULL AUTO_INCREMENT,
  dni VARCHAR(16) NOT NULL UNIQUE,
  nombres VARCHAR(150) NOT NULL,
  paterno VARCHAR(100) NOT NULL,
  materno VARCHAR(45) NOT NULL,
  correo VARCHAR(150) NOT NULL UNIQUE,
  clave BLOB NOT NULL,
  tipo INT NOT NULL,
  PRIMARY KEY (id),
  CONSTRAINT fk_usuario_tipo
    FOREIGN KEY (tipo)
    REFERENCES tipos_usuario (id)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION
)ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

-- -----------------------------------------------------
-- Insertando datos de inicialización
-- -----------------------------------------------------
INSERT INTO tipos_usuario(nombre) VALUES ("ADMINISTRADOR");

INSERT INTO usuarios(dni, nombres, paterno, materno, correo, clave, tipo)
       VALUES ('10101010','PAUL', 'GARCIA', 'MATTOS', 
       'paul@example.com', AES_ENCRYPT('2022','2022'), 1);

-- Recuperando el usuario
SELECT * FROM usuarios 
 	WHERE AES_DECRYPT(clave, '2022') = '2022';

-- Recuperando la clave
SELECT AES_DECRYPT(clave, '2022') AS clave FROM usuarios;

Archivos de conexión y configuración

Definimos los parámetros de la conexión a MySQL en el archivo config.php

<?php
date_default_timezone_set("America/Lima");
define("HOST", "localhost");
define("USUARIO", "root");    # Usuario root
define("CLAVE", "");          # Sin contraseña
define("BASE_DATOS", "blog"); # Nombre de la base de datos
define("PUERTO", "3306");     # 3306 - MySQL, 3307 - MariaBD
?>

Creamos el archivo que contiene las funciones de conexión desconexión y consultas a la base de datos conexion.php

<?php
include_once ("config.php");
$cnx = "";

# Conexión a la Base de Datos
function conectar() {
    global $cnx;
    $cnx = mysqli_connect(HOST,USUARIO,CLAVE,
           BASE_DATOS, PUERTO);
    mysqli_query($cnx, "set names utf8");
}

# Liberar la conexion con la base de datos
function desconectar() {
    global $cnx;
    mysqli_close($cnx);
}

# Ejecutar "SELECT"
function consultar($sql) {
    global $cnx;
    $result = mysqli_query($cnx, $sql);
    $salida = array();
    while ($fila = mysqli_fetch_assoc($result)) {
        $salida[] = $fila;
    }
    mysqli_free_result($result);
    unset($fila);
    return $salida;
}
?>

Formulario HTML

Creamos un formulario HTML para hacer las pruebas que llamaremos login.html en el que se verificará que el DNI y la clave coinciden. Sin embargo, se puede reemplazar DNI por correo, ya que ambos son de tipo UNIQUE en la base de datos

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Login con PHP y MySQL</title>
    </head>
    <body>
        <form method="post" action="login_procesar.php">
            DNI: <input type="text" name="txtDni"><br />
            Clave: <input type="password" name="txtClave"><br />
            <input type="submit" value="Ingresar">
        </form>           
    </body>
</html>

Documento PHP de validación

El documento PHP que valida el DNI y contraseña ingresado en el formulario llamado login_procesar.php

<?php
include_once('conexion.php');

$dni = $_POST['txtDni'];
$pass = $_POST['txtClave'];

$sql = "SELECT * FROM usuarios WHERE dni = '$dni' AND "
        . "AES_DECRYPT(clave, '$pass') = '$pass';";

conectar();
$registro = consultar($sql);
desconectar();

if (count($registro) == 1) {
    var_dump($registro[0]);
    echo "Acceso concedido";
    // header('location:  intranet.php');
} else {
    echo "Error en acceso";
    // header('location:  error.php');
}
?>

Para realizar el proceso de login se debe llamar a la página http://localhost/blog/login y colocar las credenciales indicadas. El resultado en pantalla si las credenciales son correcta debe ser algo similar a:

D:\wamp64\www\blog\login_procesar.php:15:
array (size=8)
  'id' => string '1' (length=1)
  'dni' => string '10101010' (length=8)
  'nombres' => string 'PAUL' (length=4)
  'paterno' => string 'GARCIA' (length=6)
  'materno' => string 'MATTOS' (length=6)
  'correo' => string 'paul@example.com' (length=16)
  'clave' => string 'YC�Ft��l�L�6�a�' (length=16)
  'tipo' => string '1' (length=1)
  
Acceso concedido

Estructura del proyecto