Es el sueño de todo desarrollador 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 todos los usuarios. 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, le ayuda a medir y editar su código más adelante cuando necesite reutilizarlo en otros proyectos. Dado que este artículo busca brindarle una guía sobre cómo crear una página de inicio de sesión segura en PHP y MySQL, primero debemos considerar los beneficios de este enfoque.
Creación de un script de inicio de sesión seguro en PHP y MySQL
En primer lugar, 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.
Empezando
En este tutorial de artículo, asumimos que necesita una página de inicio de sesión segura por dos razones. En primer lugar, podría estar trabajando en un sistema web dedicado en el que necesite acceso de administrador a datos o información almacenados de forma confidencial. En segundo lugar, su sistema web podría albergar 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 tutorial de artículo es nuestro entorno de servidor web. Necesitamos uno ya que nuestro sistema web utilizará 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 que se ejecuten sus proyectos PHP.
Instalación de XAMPP Linux
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 ingrese 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úrese de que las casillas anteriores estén marcadas para estar seguro.
La instalación tardará un tiempo en completarse.
El lanzamiento de 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á incluido 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. Puedes 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 está funcionando bien.
Nuestro objetivo tutorial
Una vez que haya descargado e instalado la versión XAMPP que favorece a su plataforma de sistema operativo, debemos resaltar los principales objetivos 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 balas para las inyecciones 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 tenga que introducir 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
Dado que ahora estamos seguros de que el servidor web Apache y el servidor de 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 captura de pantalla a continuación.
Si hace clic en el menú “Administrar servidores” en su encabezado, verá tres servidores en ejecución (Apache, MySQL y ProFTPD). Todos estos tres servidores deben estar funcionando. Significa que el servidor XAMPP está en buen estado.
Haga clic en el menú “Abrir carpeta de la aplicación” en este panel de control de XAMPP y rastree 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
| -- Index.html
| -- 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 “touch” para crear los archivos indicados. Por ejemplo, para crear el archivo index.html, usaría el siguiente enfoque 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 introducir los nombres de usuario y las 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 manejará la autenticación del usuario, la conexión de la base de datos, la validación de los 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 el destino o la página de destino para los usuarios que inician sesión correctamente en el sistema web.
El archivo profile.php creado asocia un usuario que inició sesión correctamente con los detalles de su cuenta de usuario completa y personalizada.
Nuestro diseño de formulario de inicio de sesión
Para que nuestro script loin 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 interfaz 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 utilizar 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 debería ser similar a la siguiente captura de pantalla.
Dado que la pantalla anterior es básica, necesitamos agregar algo de estilo 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 &ltlink&gt anterior debe estar entre las etiquetas &lthead&gt y &lt/head&gt 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.
Intentemos ahora comprender qué le hicimos a 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 alimentaremos los datos del usuario en el sistema del servidor y no los recibiremos, ya que eso requeriría el atributo “método” establecido en “obtener”. El atributo “action” 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 del formulario correctamente.
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 está encriptada durante la entrada del usuario. El tipo de entrada “enviar” es la acción final para enviar los datos de usuario capturados para su procesamiento por el archivo “authenticate.php”.
Configurar 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á una pestaña “Bases de datos”. Haga clic en él para crear una nueva base de datos. Nómbrelo 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 tutorial.
Para crear y completar 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 su interfaz. Usar la consola es mucho más eficiente ya que solo necesitamos crear una única declaración SQL para crear y completar una tabla completa. Por ejemplo, considere la siguiente declaració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', '123@456.78Nine', 'brandon@fosslinux.com')
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 (identificación, 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 PHP.
Autenticación de usuarios
En su estado, hemos creado un formulario de inicio de sesión estático atractivo y también hemos configurado nuestra base de datos MySQL. La base de datos tiene una tabla y algunos datos de usuario útiles para impulsar el siguiente paso de este tutorial. Primero, tenemos que 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 guión 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 la sesión y regresen al sitio más tarde usando la misma computadora, será fácil iniciar sesión nuevamente 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 completarse. Agregue el siguiente código a su 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 de usuario con datos que ya existen en la base de datos.
Agregue el siguiente código a su 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 identificación 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 “ ” se ocupa de este objetivo de almacenamiento de sesión. $stmt->store_result()
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 declaració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 se ocupa de evaluar la consulta de la base de datos para determinar la viabilidad de los resultados. Si el nombre de usuario introducido no está en la base de datos, no habrá nada que mostrar. Si un usuario se autentica con éxito, tiene lugar la inicialización de las variables de sesión. El servidor web almacena estas variables y el navegador web del usuario las referencia 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 incorrectos y vea qué sucede.
Por mi parte, recibí el error de captura de pantalla anterior.
Ahora inicie sesión con la combinación correcta de nombre de usuario y contraseña almacenados en su base de datos MySQL.
Nuestra página de aterrizaje
Tener una página de inicio de sesión no es suficiente para nuestro tutorial, un usuario que inicia sesión con éxito en el sistema debe ser redirigido a una página de inicio. Desde aquí, dicho usuario también tendrá la opción de cerrar la sesión del 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
}
?>
Agregue el siguiente código HTML a su archivo home.php.
<!DOCTYPE html>
<html>
<head>
<metacharset="utf-8">
<title>FossLinux Home Page</title>
<linkhref="https://www.fosslinux.com/47408/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="https://www.fosslinux.com/47408/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. Agregue el siguiente código a su 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 lo redireccionará ahora a esta página de inicio.
El script de cierre de sesión
La visualización 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 a la página de inicio de sesión.
Nota final
Con este tutorial, ahora tiene una base sólida para crear scripts PHP seguros y confiables. Ahora puede crear un sistema que sea confiable para sus usuarios o clientes objetivo. Ha manejado la vulnerabilidad de inyección de SQL y la validación y autenticación de datos de formularios. Lo que queda para usted 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 PHP y MySQL.