Login recordarme usando PDO y PHP [Ejemplo completo]
Login recordarme usando PDO. El usuario debe iniciar sesión en el sitio web utilizando su nombre de usuario o correo electrónico y contraseña para acceder al sitio web. Sin embargo, si el usuario no ha cerrado la sesión, pero destruye la SESION, debe volver a iniciar sesión en el sitio web.
¿Cómo funciona el script?
Al agregar el input (casilla de verificación) recordarme en el formulario de inicio de sesión el usuario debe marcar la casilla de verificación Recordarme e iniciar sesión en el sitio web.
Además, cuando el usuario vuelve a acceder al sitio web, no es necesario iniciar sesión y se inicia la SESSION.
En este artículo veremos cómo crear una página de inicio de sesión con recordarme y nos enfocaremos con la funcionalidad PDO PHP, MySQL.
Login recordarme usando PDO: Estructura
A continuación, veremos los elementos del presente ejemplo.
A) Base de datos
Para este ejemplo vamos a utilizar una base datos llamado «db_recordarme» y una tabla llamada «usuarios«. Po lo tanto, con estos datos realizaremos el login de usuarios.
CREATE TABLE `usuarios` ( `id` int(11) NOT NULL, `username` varchar(80) NOT NULL, `name` varchar(80) NOT NULL, `password` varchar(80) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT INTO `usuarios` (`id`, `username`, `name`, `password`) VALUES (1, 'jhon', 'Jhon Maiden', '12345'), (2, 'karla', 'karla Soria', '12345'), (3, 'vsoto', 'Valeria Soto', '12345'), (4, 'mtom', 'Mario Tom', '12345'), (5, 'gtre', 'German Trevin', '12345'), (6, 'pjon', 'pablo Jolero', '12345'), (7, 'jiren', 'Juan Iren', '12345'); ALTER TABLE `usuarios` ADD PRIMARY KEY (`id`); ALTER TABLE `usuarios` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;
B) Login recordarme usando PDO: Configuración
Hay que crear un archivo llamado config.php para una conexión de base de datos. Sin embargo, usaremos PDO para darle seguridad a nuestra conexion con MySQL.
Código completo config.php
<?php session_start(); $server = "localhost"; $username = "root"; $password = ""; $dbname = "db_recordarme"; // crear la conexion con mysql try{ $conn = new PDO("mysql:host=$server;dbname=$dbname","$username","$password"); $conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); }catch(PDOException $e){ die('Unable to connect with the database'); } ?>
C) Página de inicio de sesión
Vamos a crear un archivo llamado index.php para almacenar el código de login de usuarios y contendrá varios elementos que detallaremos a continuación.
Script HTML
- Usaremos una etiqueta <form>.
- Cree una etiqueta de texto para el nombre de usuario,
- Una etiqueta de contraseña,
- Etiqueta de casilla de verificación para recordarme
- Botón de envío
<!DOCTYPE html> <html lang="es" class="h-100"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> <title>Login recordarme usando PDO y PHP</title> </head> <body class="d-flex flex-column h-100"> <header> <!-- Fixed navbar --> <nav class="navbar navbar-expand-md navbar-dark bg-dark"> <div class="container"> <a class="navbar-brand" href="#">BaulPHP</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarCollapse"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Portada <span class="sr-only">(current)</span></a> </li> </ul> <form class="form-inline mt-2 mt-md-0"> <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search"> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Busqueda</button> </form> </div> </div> </nav> </header> <!-- Begin page content --> <hr> <br> <main> <div class="container"> <div class="row"> <div class="col-md-12"> <h3>Login recordarme usando PDO y PHP</h3> <hr> </div> <div class="col-md-6"> <div id="div_login"><div> <form method="post" action=""> <div class="mb-3"> <label for="exampleInputEmail1" class="form-label">Usuario</label> <input type="text" class="form-control" name="txt_uname" aria-describedby="emailHelp"> <div id="emailHelp" class="form-text">Usuario registrado en la BD.</div> </div> <div class="mb-3"> <label for="exampleInputPassword1" class="form-label">Password</label> <input type="password" class="form-control" name="txt_pwd"> </div> <div class="mb-3 form-check"> <input type="checkbox" class="form-check-input" name="rememberme" value="1"> <label class="form-check-label" for="exampleCheck1">Recordarme</label> </div> <button type="submit" class="btn btn-primary" name="but_submit">Iniciar sesión</button> </form> </div> </div> </div> </div> <footer> <hr> <div class="copyright"> © 2013 - <?=date("Y")?> <a href="https://baulcode.com" target="_blank">baulcode</a>. All rights reserved </div> <div class="footerlogo"><a href="https://baulcode.com" target="_blank"></a> </div> </footer> </div> </main> </body> </html>
Codigo PHP
Para lograr nuestro objetivo usaremos 2 funciones para cifrar y descifrar el ID de usuario. Por otro lado, usaremos OpenSSL para cifrar y descifrar.
- encryptCookie: esta función toma un único parámetro que es userid. Generar clave aleatoria, estoy usando el cifrado ‘aes-256-cbc’ (Puede ver otros métodos aquí). Trae la $iv.
- decryptCookie: esta función toma un único parámetro que se $ciphertext. Explote el $ciphertext por ‘::’ y asigne en variables.
Pase valores en la función openssl_decrypt() y devuélvalo.
Establezca Recordarme COOKIE si ‘rememberme’ es POST. Cifrar el ID de usuario llamando a la función encryptCookie(). Establezca el valor de $_COOKIE[‘rememberme’] durante 30 días.
Si se establece, descifre el $_COOKIE [‘rememberme’] omitiendo en la función decryptCookie() y obtenga el ID de usuario. Compruebe si el ID de usuario existe o no. Si existe, establezca $_SESSION[‘userid’] y redirija a main.php.
<?php include "config.php"; // Encrypt cookie function encryptCookie( $userid ) { $key = hex2bin(openssl_random_pseudo_bytes(4)); $cipher = "aes-256-cbc"; $ivlen = openssl_cipher_iv_length($cipher); $iv = openssl_random_pseudo_bytes($ivlen); $ciphertext = openssl_encrypt($userid, $cipher, $key, 0, $iv); return( base64_encode($ciphertext . '::' . $iv.'::'.$key) ); } // Decrypt cookie function decryptCookie( $ciphertext ) { $cipher = "aes-256-cbc"; list($encrypted_data, $iv,$key) = explode('::', base64_decode($ciphertext)); return openssl_decrypt($encrypted_data, $cipher, $key, 0, $iv); } // Check if $_SESSION or $_COOKIE already set if( isset($_SESSION['userid']) ){ header('Location: home.php'); exit; }else if( isset($_COOKIE['rememberme'] )){ // Decrypt cookie variable value $userid = decryptCookie($_COOKIE['rememberme']); // Fetch records $stmt = $conn->prepare("SELECT count(*) as cntUser FROM users WHERE id=:id"); $stmt->bindValue(':id', (int)$userid, PDO::PARAM_INT); $stmt->execute(); $count = $stmt->fetchColumn(); if( $count > 0 ){ $_SESSION['userid'] = $userid; header('Location: main.php'); exit; } } // On submit if(isset($_POST['but_submit'])){ $username = $_POST['txt_uname']; $password = $_POST['txt_pwd']; if ($username != "" && $password != ""){ // Fetch records $stmt = $conn->prepare("SELECT count(*) as cntUser,id FROM usuarios WHERE username=:username and password=:password "); $stmt->bindValue(':username', $username, PDO::PARAM_STR); $stmt->bindValue(':password', $password, PDO::PARAM_STR); $stmt->execute(); $record = $stmt->fetch(); $count = $record['cntUser']; if($count > 0){ $userid = $record['id']; if( isset($_POST['rememberme']) ){ // Set cookie variables $days = 30; $value = encryptCookie($userid); setcookie ("rememberme",$value,time()+ ($days * 24 * 60 * 60 * 1000)); } $_SESSION['userid'] = $userid; header('Location: main.php'); exit; }else{ echo "Invalid username and password"; } } } ?>
D) Página de inicio
- Crearemos un archivo llamado main.php para mostrar al usuario logueado.
- Compruebe si $_SESSION[‘userid’] está establecido o no. Si no está establecido, redirija al archivo index.php.
- Al cerrar la sesión, haga clic en el botón destruir la SESION y eliminar la COOKIE ‘rememberme‘ estableciéndola la hora en el pasado.
E) Panel de control con login
Este panel se muestra si el usuario ha accedido correctamente y sus credenciales coinciden con la base de datos. A continuación veamos el script.
Código completo
<?php include "config.php"; ?> <!DOCTYPE html> <html lang="es" class="h-100"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> <title>Login recordarme usando PDO y PHP</title> </head> <body class="d-flex flex-column h-100"> <header> <!-- Fixed navbar --> <nav class="navbar navbar-expand-md navbar-dark bg-dark"> <div class="container"> <a class="navbar-brand" href="#">BaulPHP</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarCollapse"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Portada <span class="sr-only">(current)</span></a> </li> </ul> <form class="form-inline mt-2 mt-md-0"> <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search"> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Busqueda</button> </form> </div> </div> </nav> </header> <!-- Begin page content --> <hr> <br> <main> <div class="container"> <div class="row"> <div class="col-md-12"> <h3>Panel de control</h3> <hr> </div> <div class="col-md-6"> <?php // Check user login or not if(!isset($_SESSION['userid'])){ header('Location: index.php'); } // logout if(isset($_POST['but_logout'])){ session_destroy(); // Remove cookie variables $days = 30; setcookie ("rememberme","", time() - ($days * 24 * 60 * 60 * 1000) ); header('Location: index.php'); } ?> <form method='post' action=""> <input class="btn btn-danger" type="submit" value="Salir" name="but_logout"> </form> </div> </div> <footer> <hr> <div class="copyright"> © 2013 - <?=date("Y")?> <a href="https://baulcode.com" target="_blank">baulcode</a>. All rights reserved </div> <div class="footerlogo"><a href="https://baulcode.com" target="_blank"></a> </div> </footer> </div> </main> </body> </html>
Conclusión
La función setcookie() en el botón de cierre de sesión clic en index.php archivo para comprobar si recuerdo que estoy funcionando o no y también puedes reducir el tiempo de expiración de COOKIE.
Si funciona, se crea SESSION cuando se ejecuta index.php archivo y la página se redirige al archivo main.php.
Hemos aprendido a usar la opción recordarme del formulario HTML
Te agradezco enormemente el tiempo que dedicas para compartir, excelente explicación, solo una pregunta donde guardaría el archivo config php para que no fuera visible.
Saludos y de antemano gracias.
Muchas gracias Samuel, puedes intentar ofuscar el código del archivo de conexión
Saludos
Hola Nestor
¿Que tendría que cambiar si tengo mi tabla de usuarios encriptada en sha1 para que me reconozca las contraseñas?
Gracias por adelantado
Me había hecho todo un mundo, y la forma de hacerlo era mas simple, buen tutorial me sirvió mucho.