El sueño de todo desarrollador es crear o trabajar en una página web o proyecto web que prometa características de seguridad de primer nivel y satisfaga las preocupaciones de privacidad de cada usuario. Sin embargo, antes de que pueda crear y alojar un sitio web en un servidor, debe cumplir con las mejores prácticas de codificación.
El hecho de que desee crear una página web segura no significa que su código solo deba ser comprensible para los ojos de un científico espacial. La simplicidad es clave para desarrollar un código asombroso.
Un código simple no es un código débil sino comprensible. La simplicidad se aplica a la refactorización de código y al uso continuo de comentarios. Además, te ayuda a medir y editar tu código más adelante cuando necesites reutilizarlo en otros proyectos. Dado que este artículo busca brindarle una guía para crear una página de inicio de sesión segura en PHP y MySQL, primero debemos considerar los beneficios de este enfoque.
Crear un script de inicio de sesión seguro en PHP y MySQL
Primero, dado que su página de inicio de sesión otorgará acceso privilegiado a la información almacenada por el usuario, querrá evitar que los ladrones cibernéticos y los piratas informáticos comprometan fácilmente su sistema y se salgan con la suya con datos confidenciales. En segundo lugar, sin una plataforma web segura, las infraestructuras de TI, como las redes y los sitios web, corren el riesgo de sufrir ataques de ciberseguridad y malware.
Cómo empezar
En este tutorial del artículo, asumimos que necesita una página de inicio de sesión segura por dos razones. Primero, podría estar trabajando en un sistema web dedicado donde necesita acceso de administrador a datos o información almacenados de manera confidencial. En segundo lugar, su sistema web podría acomodar usuarios o visitantes específicos a los que se les asignarán las credenciales de inicio de sesión necesarias antes de que puedan iniciar sesión en el área del panel de control de su sistema web.
El aspecto más importante de este artículo tutorial es nuestro entorno de servidor web. Necesitamos uno ya que nuestro sistema web usará una base de datos MySQL para consultar a los usuarios activos y otorgarles acceso autorizado al sistema web creado.
Requisitos
XAMPP es un entorno de servidor web local ideal para probar sus proyectos basados en web en una máquina local. Le brinda la perspectiva de rendimiento de los sitios web antes de lanzarlos en un entorno de producción. XAMPP está disponible para usuarios de Windows, Linux y OS X, lo que lo convierte en un entorno de servidor web multiplataforma. Además, XAMPP abrevia Apache, MariaDB (una bifurcación de MySQL), PHP y Perl, lo que lo convierte en un entorno de desarrollo PHP completo.
Una vez que instale XAMPP, no necesita instalar ningún otro software de terceros para ejecutar sus proyectos PHP.
Instalación de Linux XAMPP
La descarga de su archivo XAMPP tendrá una extensión ".run". El primer paso es hacerlo ejecutable. Abra su terminal en la ubicación de su archivo XAMPP descargado y considere el siguiente enfoque. Asegúrese de que el nombre del archivo XAMPP que ingresa coincida con el que descargó.
$ chmod 755 xampp-linux-x64-8.0.7-0-installer.run
Luego, debería poder iniciar el instalador de XAMPP con el siguiente comando.
$ sudo ./xampp-linux-x64-8.0.7-0-installer.run
Siga los pasos de instalación hasta que XAMPP esté completamente instalado en su computadora.
Asegúrate de que las casillas anteriores estén marcadas para que sea seguro.
La instalación tardará un tiempo en completarse
Lanzar XAMPP desde su terminal de Ubuntu requiere el uso del siguiente comando.
$ sudo /opt/lampp/lampp start
Una salida como la siguiente captura de pantalla significa que todo está bien.
Si se encuentra con errores al iniciar XAMPP, podría haber tres soluciones de diagnóstico para el problema. Primero, es posible que haya instalado Apache y XAMPP simultáneamente. Puede resolver este problema deteniendo el servicio Apache desde la terminal y reiniciando XAMPP, ya que Apache ya está integrado como uno de sus paquetes.
$ sudo /etc/init.d/apache2 stop
$ sudo /opt/lampp/lampp start
Un servidor NGINX instalado también podría estar usando el puerto 80 de su máquina que necesita Apache de XAMPP. Por lo tanto, deberá detener NGINX y reiniciar XAMPP.
$ sudo systemctl stop nginx
$ sudo /opt/lampp/lampp start
También podría tener un servidor MySQL instalado simultáneamente con XAMPP. El servidor XAMPP ya está incluido con un paquete MySQL. Deberá detener el que se está ejecutando en su sistema.
$ sudo /etc/init.d/mysql stop
$ sudo /opt/lampp/lampp start
El problema final es que podría estar perdiendo la herramienta netstat en su sistema. Puede instalarlo con el siguiente comando.
$ sudo apt install net-tools
Para verificar la instalación exitosa de XAMPP en su sistema, debería poder acceder cómodamente a la siguiente URL desde su navegador.
http://localhost/dashboard/
La página de destino debe parecerse a la siguiente captura de pantalla.
También debería poder acceder cómodamente a la página de inicio de phpMyAdmin.
http://localhost/phpmyadmin
La siguiente captura de pantalla verifica que phpMyAdmin funciona correctamente.
Nuestro objetivo tutorial
Una vez que haya descargado e instalado la versión de XAMPP que favorece su plataforma de sistema operativo, debemos resaltar los objetivos principales de este artículo.
Al final de este artículo tutorial, habrá entendido los siguientes cuatro conceptos principales detrás de la creación de una página de inicio de sesión segura en PHP y MySQL.
-
Diseño de formularios:aquí, debe explorar algunos módulos de HTML5 y CSS3
-
Preparación de consultas SQL:las consultas SQL que cree deben ser a prueba de inyecciones de SQL. Es la única forma de mantener la integridad de su base de datos MySQL.
-
Validación de formulario básico:el nombre de usuario y la contraseña de un usuario deben coincidir con los almacenados en la base de datos para que no sean credenciales válidas.
-
Gestión de sesiones:las sesiones son buenas ya que un sistema debe recordar a un usuario repetitivo sin que tengan que ingresar sus credenciales de inicio de sesión cada vez que visitan un sitio. Podrá inicializar sesiones y mantenerlas activas.
Estructura y configuración del proyecto
Como ahora estamos seguros de que el servidor web Apache y el servidor de la base de datos MySQL se están ejecutando, el siguiente paso es crear nuestro código PHP. Pero, primero, debemos familiarizarnos con su panel de control. Cuando se completa la instalación de XAMPP, se inicia con un panel de control que se parece a la siguiente captura de pantalla.
Si hace clic en el menú "Administrar servidores" en su encabezado, verá tres servidores en ejecución (Apache, MySQL y ProFTPD). Estos tres servidores deben estar funcionando. Significa que el servidor XAMPP está en buen estado.
Haga clic en el menú "Abrir carpeta de aplicaciones" en este panel de control de XAMPP y busque un directorio llamado "htdocs". A continuación, cree una carpeta con un nombre como "fosslinux_login" dentro de este directorio. Será el principal punto de acceso de nuestro proyecto. Dentro de esta carpeta "fosslinux_login", cree los siguientes archivos y considere sus respectivas extensiones de archivo.
\ -- Project files structure
| -- authenticate.php
| -- home.php
| --
| -- logout.php
| -- style.css
La forma más sencilla de lograr esta asignación de creación de archivos es navegar a la interfaz gráfica de la carpeta "fosslinux_login" y abrir el terminal del sistema desde su ubicación, y luego usar el comando "tocar" para crear los archivos indicados. Por ejemplo, para crear el archivo index.html, usaría el siguiente método de comando táctil.
root@FOSSlinux:/opt/lampp/htdocs/fosslinux_login# touch index.html
El archivo index.html creado utilizará principalmente los lenguajes de programación HTML5 y CSS3 para crear el formulario de inicio de sesión para ingresar los nombres de usuario y contraseñas necesarios.
El archivo style.css creado actuará como un script CSS externo al que hace referencia el encabezado del archivo index.html.
El archivo authenticate.php creado se encargará de la autenticación del usuario, la conexión a la base de datos, la validación de datos del formulario, la recuperación de los resultados de la base de datos y la creación de nuevas sesiones.
El archivo logout.php creado manejará la destrucción de las sesiones de inicio de sesión antes de redirigir al usuario a la pantalla de inicio de sesión nuevamente.
El archivo home.php creado es la página de destino o destino para los usuarios que inician sesión correctamente en el sistema web.
El archivo profile.php creado asocia a un usuario que inició sesión con éxito con sus detalles de cuenta de usuario completos y personalizados.
Nuestro diseño de formulario de inicio de sesión
Para que nuestro script loin de PHP y MySQL funcione, necesitamos crear un formulario de inicio de sesión desde el cual los usuarios autenticados ingresarán su información de inicio de sesión. Por lo tanto, estamos creando la parte frontal de nuestra página de inicio de sesión. Solo necesitamos CSS y HTLM para esta tarea. Usaremos PHP para la parte lógica de nuestro script.
Puede usar el editor nano o cualquier otro editor de su elección para abrir el archivo index.html que creó anteriormente.
root@FOSSlinux:/opt/lampp/htdocs/fosslinux_login# nano index.html
Complete el archivo con el siguiente segmento de código.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>FossLinux Login Tutorial</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
</head>
<body>
<div class="login">
<h1>FossLinux Login Tutorial</h1>
<form action="authenticate.php" method="post">
<label for="username">
<i class="fas fa-user"></i>
</label>
<input type="text" name="username" placeholder="Username" id="username" required>
<label for="password">
<i class="fas fa-lock"></i>
</label>
<input type="password" name="password" placeholder="Password" id="password" required>
<input type="submit" value="Login">
</form>
</div>
</body>
</html>
Ahora necesitamos obtener una vista previa de la pantalla resultante de este código. En su navegador, introduzca la siguiente dirección.
http://localhost/fosslinux_login
La pantalla resultante debe ser similar a la siguiente captura de pantalla.
Dado que la visualización anterior es básica, debemos agregar algunos estilos a nuestro formulario de inicio de sesión a través de CSS. Entonces, primero, abra el archivo style.css que creó anteriormente con su editor de terminal favorito.
root@FOSSlinux:/opt/lampp/htdocs/fosslinux_login# nano style.css
Rellénelo con el siguiente segmento de código CSS.
* {
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "segoe ui", roboto, oxygen, ubuntu, cantarell, "fira sans", "droid sans", "helvetica neue", Arial, sans-serif;
font-size: 16px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
background-color: #435165;
}
.login {
width: 400px;
background-color: #ffffff;
box-shadow: 0 0 9px 0 rgba(0, 0, 0, 0.3);
margin: 100px auto;
}
.login h1 {
text-align: center;
color: #5b6574;
font-size: 24px;
padding: 20px 0 20px 0;
border-bottom: 1px solid #dee0e4;
}
.login form {
display: flex;
flex-wrap: wrap;
justify-content: center;
padding-top: 20px;
}
.login form label {
display: flex;
justify-content: center;
align-items: center;
width: 50px;
height: 50px;
background-color: #3274d6;
color: #ffffff;
}
.login form input[type="password"], .login form input[type="text"] {
width: 310px;
height: 50px;
border: 1px solid #dee0e4;
margin-bottom: 20px;
padding: 0 15px;
}
.login form input[type="submit"] {
width: 100%;
padding: 15px;
margin-top: 20px;
background-color: #3274d6;
border: 0;
cursor: pointer;
font-weight: bold;
color: #ffffff;
transition: background-color 0.2s;
}
.login form input[type="submit"]:hover {
background-color: #2868c7;
transition: background-color 0.2s;
}
Necesitamos vincular este archivo style.css a nuestro archivo index.html para presenciar los cambios notables. Agregue lo siguiente al encabezado de su archivo index.html.
<link href="style.css" rel="stylesheet" type="text/css">
La etiqueta anterior debe estar entre las etiquetas
y en su archivo index.html.Si actualiza la página de visualización de inicio de sesión, debería obtener una vista previa de un formulario de inicio de sesión más atractivo, como se muestra en la siguiente captura de pantalla.
Tratemos ahora de entender lo que hicimos con nuestro formulario de inicio de sesión. La forma posee dos atributos, “acción” y “método”. El atributo "método" se establece en "publicar", ya que introduciremos datos de usuario en el sistema del servidor y no los recibiremos, ya que eso requeriría que el atributo "método" se establezca en "obtener". El atributo "acción" se establece en "authenticate.php" porque ese es el archivo que maneja la autenticación de los datos de usuario ingresados. Es el archivo que procesa las entradas de datos de formulario exitosas.
En cuanto a los campos del formulario, los tipos de entrada son "texto" para el nombre de usuario y "contraseña" para la contraseña del usuario. La entrada de "texto" será visible para el ojo humano, a diferencia de la entrada de "contraseña" que se supone que debe estar encriptada durante la entrada del usuario. El tipo de entrada "enviar" es la acción final para enviar los datos de usuario capturados para que los procese el archivo "authenticate.php".
Configuración de la base de datos y las tablas necesarias
Aquí, deberá navegar hasta el enlace "http://localhost/phpmyadmin/" para acceder a la base de datos MySQL. La interfaz phpMyAdmin resultante tiene la función principal de administrar una aplicación de base de datos MySQL.
En la parte superior de esta interfaz, verá la pestaña "Bases de datos". Haga clic en él para crear una nueva base de datos. Nómbralo algo así como "fosslinuxlogin".
Una vez que haga clic en "crear", la nueva base de datos (fosslinuxlogin) aparecerá en la sección/panel del menú izquierdo de la pantalla. Su tarea neta sería crear las tablas necesarias para su base de datos. Solo necesitamos una tabla para este artículo de tutorial.
Para crear y llenar una tabla con phpMyAdmin, tiene la opción de hacerlo gráficamente o usar la pantalla de la consola en la parte inferior de la pantalla de la interfaz. Usar la consola es mucho más eficiente, ya que solo necesitamos crear una sola declaración SQL para crear y completar una tabla completa. Por ejemplo, considere la siguiente instrucción de código SQL.
CREATE TABLE IF NOT EXISTS `accounts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO `accounts` (`id`, `username`, `password`, `email`) VALUES (1, 'Brandon', '[email protected]', '[email protected]');
Como se muestra en las capturas de pantalla a continuación, una vez que presione Ctrl+Enter en su teclado, se ejecutará la instrucción SQL y se completará la tabla de su base de datos.
Hemos creado una base de datos de cuentas con cuatro columnas (id, nombre de usuario, contraseña y correo electrónico). También hemos asignado a estas columnas de la tabla algunos valores predeterminados, pero principalmente necesitaremos los valores de nombre de usuario y contraseña para probar el script de inicio de sesión de PHP.
Autenticación de usuarios
En su estado, hemos creado un atractivo formulario de inicio de sesión estático y también configuramos nuestra base de datos MySQL. La base de datos tiene una tabla y algunos datos de usuario útiles para impulsar el próximo paso de este tutorial. Primero, necesitamos trabajar en el archivo authenticate.php vinculado al atributo "acción" de la pantalla de nuestro formulario de inicio de sesión.
Usando su editor de terminal favorito, complete el archivo authenticate.php creado con los siguientes datos.
<?php
session_start();
// Change this connection setting to your preference.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$DATABASE_NAME = 'fosslinuxlogin';
// Try and connect using the info above.
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if ( mysqli_connect_errno() ) {
// If there is an error with the connection, stop the script and display the error.
exit('Failed to connect to MySQL: ' . mysqli_connect_error());
}
El script comienza iniciando una sesión. Este paso es ventajoso ya que el servidor web recuerda los detalles de inicio de sesión de la cuenta de usuario. Entonces, cuando los mismos usuarios cierren sesión y regresen al sitio más tarde usando la misma computadora, será fácil volver a iniciar sesión sin ingresar un nuevo nombre de usuario y contraseña.
También especificamos la base de datos a la que deseamos conectarnos junto con su host, usuario y contraseña, si corresponde.
El primer paso para autenticar nuestro formulario de inicio de sesión es asegurarse de que un usuario no pueda enviar un formulario vacío. Ambos campos deben ser llenados. Agrega el siguiente código a tu archivo authenticate.php para ayudarnos a lograr este objetivo.
// Time to check if the login form data was submitted. The isset() function checks if the form data exists.
if ( !isset($_POST['username'], $_POST['password']) ) {
// Could not fetch any data from form subbmission
exit('Please make sure you filled both the username and password form fields!');
}
Con el fragmento de código anterior, un usuario recibirá un error al enviar un formulario vacío. Dado que hemos manejado envíos de formularios en blanco, ahora necesitamos autenticar el envío del formulario del usuario con datos que ya existen en la base de datos.
Agrega el siguiente código a tu archivo authenticate.php.
// We need to Prepare our SQL. This SQL preparation helps prevent SQL injections
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc). Since a string is the username in our case, we use "s"
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
// Store or preserve the results. It helps counter-check if the user account exists within our database.
$stmt->store_result();
$stmt->close();
}
?>
Los valores de identificación y contraseña se seleccionan de la tabla de la base de datos y se comparan con las entradas del usuario. Vincula los valores de id y contraseña al valor del nombre de usuario. Una vez que la instrucción SQL se ejecuta con éxito, los resultados se almacenan para usarse como sesiones. Como puede ver en el código anterior, la línea “$stmt->store_result();
” se encarga de este objetivo de almacenamiento de sesión.
La siguiente línea de código para agregar a su archivo authenticate.php debe tener éxito con la siguiente declaración de código:
$stmt->store_result();
Agregue el siguiente fragmento de código después de la instrucción de código resaltada anteriormente.
if ($stmt->num_rows > 0) {
$stmt->bind_result($id, $password);
$stmt->fetch();
// At this point, the account exists. The only thing left is to verify the password.
// The use of password_hash in the registration file is encouraged for the storage of hashed passwords.
if ($_POST['password'] === $password) {
// Verification was a success! Use log in took place!
// Sessions creation takes place because a user is logged in. Sessions functionality resemble cookies because they can remember the server's data.
session_regenerate_id();
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
echo 'Welcome ' . $_SESSION['name'] . '!';
} else {
// Incorrect password
echo 'Incorrect username and/or password!';
}
} else {
// Incorrect username
echo 'Incorrect username and/or password!';
}
El código anterior trata de evaluar la consulta de la base de datos para determinar la viabilidad de cualquier resultado. Si el nombre de usuario ingresado no está en la base de datos, no habrá nada que mostrar. Si un usuario se autentica con éxito, se lleva a cabo la inicialización de las variables de sesión. El servidor web almacena estas variables y el navegador web del usuario hace referencia a ellas para determinar el estado de inicio de sesión del mismo usuario.
Es hora de probar la viabilidad de nuestro código de autenticación. Actualice su enlace "http://localhost/fosslinux_login/" antes de continuar.
Intente iniciar sesión con una combinación de nombre de usuario y contraseña incorrecta y vea qué sucede.
Por mi parte, obtuve el error de captura de pantalla anterior.
Ahora inicie sesión con la combinación correcta de nombre de usuario y contraseña almacenada en su base de datos MySQL.
Nuestra página de destino
Tener una página de inicio de sesión no es suficiente para nuestro tutorial, un usuario que inicie sesión correctamente en el sistema debe ser redirigido a una página de inicio. Desde aquí, dicho usuario también tendrá la opción de cerrar sesión en el sistema si le conviene. Primero, complete su archivo home.php creado con el siguiente fragmento de código.
<?php
// We should always remember to use sessions. Te code statement belows start should always be used to start sessions.
session_start();
// A user not actively logged-in is redirected to the main login page...
if (!isset($_SESSION['loggedin'])) {
header('Location: index.html');
exit;
}
?>
Agrega el siguiente código HTML a tu archivo home.php.
<!DOCTYPE html>
<html>
<head>
<metacharset="utf-8">
<title>FossLinux Home Page</title>
<linkhref="style.css"rel="stylesheet"type="text/css">
<linkrel="stylesheet"href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
</head>
<bodyclass="loggedin">
<navclass="navtop">
<div>
<h1>FossLinux Login Tutorial</h1>
<ahref="logout.php"><iclass="fas fa-sign-out-alt"></i>Logout</a>
</div>
</nav>
<divclass="content">
<h2>FossLinux Home Page</h2>
<p>Welcome back, <?=$_SESSION['name']?>!</p>
</div>
</body>
</html>
Esta página de inicio también necesita algo de estilo. Agrega el siguiente código a tu archivo style.css.
.navtop {
background-color: #2f3947;
height: 60px;
width: 100%;
border: 0;
}
.navtop div {
display: flex;
margin: 0 auto;
width: 1000px;
height: 100%;
}
.navtop div h1, .navtop div a {
display: inline-flex;
align-items: center;
}
.navtop div h1 {
flex: 1;
font-size: 24px;
padding: 0;
margin: 0;
color: #eaebed;
font-weight: normal;
}
.navtop div a {
padding: 0 20px;
text-decoration: none;
color: #c1c4c8;
font-weight: bold;
}
.navtop div a i {
padding: 2px 8px 0 0;
}
.navtop div a:hover {
color: #eaebed;
}
body.loggedin {
background-color: #f3f4f7;
}
.content {
width: 1000px;
margin: 0 auto;
}
.content h2 {
margin: 0;
padding: 25px 0;
font-size: 22px;
border-bottom: 1px solid #e0e0e3;
color: #4a536e;
}
.content > p, .content > div {
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1);
margin: 25px 0;
padding: 25px;
background-color: #fff;
}
.content > p table td, .content > div table td {
padding: 5px;
}
.content > p table td:first-child, .content > div table td:first-child {
font-weight: bold;
color: #4a536e;
padding-right: 15px;
}
.content > div p {
padding: 5px;
margin: 0 0 10px 0;
}
Dado que ahora tenemos una página de inicio en su archivo authenticate.php, sustituya la siguiente línea:
echo 'Welcome ' . $_SESSION['name'] . '!';
Con esta línea:
header('Location: home.php');
Cada inicio de sesión sucesivo ahora lo redirigirá a esta página de inicio.
La secuencia de comandos de cierre de sesión
La pantalla de la página de inicio anterior tiene un enlace de cierre de sesión que debemos implementar. Un script de cierre de sesión para su archivo logout.php es tan simple como el siguiente fragmento de código.
<?php
session_start();
session_destroy();
// Redirects the user to the index.html login page:
header('Location: index.html');
?>
Dado que las sesiones determinan el estado de inicio de sesión, el script anterior destruye cualquier sesión existente y revoca el estado de inicio de sesión de ese usuario. Finalmente, este script PHP lleva al usuario de vuelta a la página de inicio de sesión.
Nota final
Con este tutorial, ahora tiene una base sólida para crear scripts PHP confiables y seguros. Ahora puede crear un sistema que sea confiable para sus usuarios o clientes objetivo. Ha manejado la vulnerabilidad de inyección SQL y la validación y autenticación de datos de formulario. Lo que le queda es una pequeña exposición sobre el segmento de código cubierto, y estará en camino de convertirse en un desarrollador senior de PHP:codificación feliz y crecimiento feliz en su viaje de PHP y MySQL.