Login y sesiones en un sitio web - Páginas login.html, login.php y datosusuarios.php

La página de entrada al sitio web que requiere autenticación es el archivo 'login.html', en el navegador se muestra la siguiente interfaz:

Login php

Veamos primero las partes fundamentales del archivo login.html

login.html
<!DOCTYPE html>
<html lang="es">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Login</title>

  <link href="bootstrap-4.3.1/css/bootstrap.min.css" rel="stylesheet">
  <script src="js/jquery-3.4.1.js"></script>
  <script src="js/popper.min.js"></script>
  <script src="bootstrap-4.3.1/js/bootstrap.min.js"></script>
  <style>
    body,
    html {
      height: 100%;
    }
  </style>
</head>

<body>
  <div class="container h-100">
    <div class="row justify-content-center h-100 align-items-center">
      <form style="border:1px solid black;padding:1rem;border-radius: 0.5rem;">
        <div class="form-group">
          <label for="Usuario">Nombre de usuario</label>
          <input type="text" class="form-control" id="Usuario" required>
        </div>
        <div class="form-group">
          <label for="Clave">Clave</label>
          <input type="password" class="form-control" id="Clave" required>
        </div>
        <div class="form-group">
          <button type="button" class="btn btn-primary" id="BotonLogin">Ingresar</button>
        </div>
        <div class="form-group">
          <a href="#" id="NuevoUsuario">Nuevo usuario?</a>
        </div>
      </form>
    </div>
  </div>

  <!-- Formulario Agregar Usuario -->
  <div class="modal fade" id="FormularioNuevoUsuario" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-dialog-centered" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">×</span>
          </button>
        </div>
        <div class="modal-body">
          <input type="hidden" id="Codigo">
          <div class="form-row">
            <div class="form-group col-md-12">
              <label>Nombre de usuario:</label>
              <input type="text" id="NombreNuevo" class="form-control">
            </div>
          </div>

          <div class="form-row">
            <div class="form-group col-md-12">
              <label>Clave:</label>
              <input type="password" id="Clave1" class="form-control">
            </div>
          </div>

          <div class="form-row">
            <div class="form-group col-md-12">
              <label>Repita clave:</label>
              <input type="password" id="Clave2" class="form-control">
            </div>
          </div>

        </div>
        <div class="modal-footer">

          <button type="button" id="BotonAgregarUsuario" class="btn btn-success">Agregar</button>
          <button type="button" class="btn btn-success" data-dismiss="modal">Cancelar</button>

        </div>
      </div>
    </div>
  </div>

  <script>
    document.addEventListener("DOMContentLoaded", function () {

      $('#NuevoUsuario').click(function () {
        borrarFormulario();
        $("#FormularioNuevoUsuario").modal();
      });

      $('#BotonAgregarUsuario').click(function () {
        let nuevousuario = retornarNuevoUsuario();
        if (validarEntradaDatos(nuevousuario))
          agregarNuevoUsuario(nuevousuario);
      });

      $('#BotonLogin').click(function () {
        let usuario = retornarUsuario();
        loginUsuario(usuario);
      });

      function borrarFormulario() {
        $('#NombreNuevo').val("");
        $('#Clave1').val("");
        $('#Clave2').val("");

      }

      function retornarNuevoUsuario() {
        let nuevousuario = {
          nombrenuevo: $('#NombreNuevo').val(),
          clave1: $('#Clave1').val(),
          clave2: $('#Clave2').val()
        };
        return nuevousuario;
      }

      function retornarUsuario() {
        let usuario = {
          usuario: $('#Usuario').val(),
          clave: $('#Clave').val()
        };
        return usuario;
      }

      function validarEntradaDatos(nuevousuario) {
        if (nuevousuario.nombrenuevo == '') {
          alert('No puede ingresar un usuario vacío');
          return false;
        }
        if (nuevousuario.clave1 == '') {
          alert('No puede ingresar una clave vacía');
          return false;
        }
        if (nuevousuario.clave1 != nuevousuario.clave2) {
          alert('Las claves ingresadas son distintas');
          return false;
        }
        return true;
      }

      function agregarNuevoUsuario(nuevousuario) {
        $.ajax({
          type: 'POST',
          url: 'datosusuarios.php?accion=existe',
          data: nuevousuario,
          success: function (info) {
            if (info.resultado == 'norepetido') {
              $.ajax({
                type: 'POST',
                url: 'datosusuarios.php?accion=agregar',
                data: nuevousuario,
                success: function () {
                  alert('se agrego el usuario');
                  $("#FormularioNuevoUsuario").modal('hide');
                },
                error: function () {
                  alert('Error');
                }
              });
            } else
              alert('Nombre de usuario existente.');
          },
          error: function () {
            alert('Error');
          }
        });
      }

      function loginUsuario(usuario) {
        $.ajax({
          type: 'POST',
          url: 'login.php',
          data: usuario,
          success: function (respuesta) {
            if (respuesta == 'correcta') {
              window.location = 'index.php';
            }
            else
              alert('nombre de usuario o clave incorrecta');
          },
          error: function () {
            alert('Error');
          }
        });
      }

    });	
  </script>

</body>

</html>

Para que se muestre el diálogo centrado en forma vertical debemos definir la propiedad 'height' para las etiquetas 'body' y 'html' con el valor 100%:

  <style>
    body,
    html {
      height: 100%;
    }
  </style>

Luego el código HTML del formulario es:

  <div class="container h-100">
    <div class="row justify-content-center h-100 align-items-center">
      <form style="border:1px solid black;padding:1rem;border-radius: 0.5rem;">
        <div class="form-group">
          <label for="Usuario">Nombre de usuario</label>
          <input type="text" class="form-control" id="Usuario" required>
        </div>
        <div class="form-group">
          <label for="Clave">Clave</label>
          <input type="password" class="form-control" id="Clave" required>
        </div>
        <div class="form-group">
          <button type="button" class="btn btn-primary" id="BotonLogin">Ingresar</button>
        </div>
        <div class="form-group">
          <a href="#" id="NuevoUsuario">Nuevo usuario?</a>
        </div>
      </form>
    </div>
  </div>

Cuando se presiona el enlace 'Nuevo usuario?' se captura con JQuery el evento:

      $('#NuevoUsuario').click(function () {
        borrarFormulario();
        $("#FormularioNuevoUsuario").modal();
      });

Al presionar el enlace 'Nuevo usuario?' se hace visible el diálogo:

  <!-- Formulario Agregar Usuario -->
  <div class="modal fade" id="FormularioNuevoUsuario" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-dialog-centered" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">×</span>
          </button>
        </div>
        <div class="modal-body">
          <input type="hidden" id="Codigo">
          <div class="form-row">
            <div class="form-group col-md-12">
              <label>Nombre de usuario:</label>
              <input type="text" id="NombreNuevo" class="form-control">
            </div>
          </div>

          <div class="form-row">
            <div class="form-group col-md-12">
              <label>Clave:</label>
              <input type="password" id="Clave1" class="form-control">
            </div>
          </div>

          <div class="form-row">
            <div class="form-group col-md-12">
              <label>Repita clave:</label>
              <input type="password" id="Clave2" class="form-control">
            </div>
          </div>

        </div>
        <div class="modal-footer">

          <button type="button" id="BotonAgregarUsuario" class="btn btn-success">Agregar</button>
          <button type="button" class="btn btn-success" data-dismiss="modal">Cancelar</button>

        </div>
      </div>
    </div>
  </div>

Luego que el usuario ingresa el nombre que desea y define su clave, pasa a presionar el botón 'Agregar' que capturamos con JQuery:

      $('#BotonAgregarUsuario').click(function () {
        let nuevousuario = retornarNuevoUsuario();
        if (validarEntradaDatos(nuevousuario))
          agregarNuevoUsuario(nuevousuario);
      });

La función 'agregarNuevoUsuario' es la que tiene por objetivo conectarse con el servidor para controlar si dicho nombre de usuario no está en uso y en caso afirmativo proceder a efecturar el nuevo registro de usuario:

      function agregarNuevoUsuario(nuevousuario) {
        $.ajax({
          type: 'POST',
          url: 'datosusuarios.php?accion=existe',
          data: nuevousuario,
          success: function (info) {
            if (info.resultado == 'norepetido') {
              $.ajax({
                type: 'POST',
                url: 'datosusuarios.php?accion=agregar',
                data: nuevousuario,
                success: function () {
                  alert('se agrego el usuario');
                  $("#FormularioNuevoUsuario").modal('hide');
                },
                error: function () {
                  alert('Error');
                }
              });
            } else
              alert('Nombre de usuario existente.');
          },
          error: function () {
            alert('Error');
          }
        });
      }

Como podemos ver hacemos una primera conexión con el servidor para validar la existencia del nombre de usuario y si nos retorna como respuesta que no existe procede con una segunda conexión AJAX para efecturar el alta de usuario.

El archivo 'datosusuarios.php' contiene los algoritmos de consulta de existencia de usuario y registro de un nuevo usuario.

datosusuarios.php
<?php
header('Content-Type: application/json');

require("conexion.php");

$conexion = retornarConexion();

switch ($_GET['accion']) {
  case 'agregar':
    $nombre = mysqli_real_escape_string($conexion, $_POST['nombrenuevo']);
    $clave = mysqli_real_escape_string($conexion, $_POST['clave1']);
    $respuesta = mysqli_query($conexion, "insert into usuarios(nombre,clave) values ('$nombre','$clave')");
    echo json_encode($respuesta);
    break;
  case 'existe':
    $nombre = mysqli_real_escape_string($conexion, $_POST['nombrenuevo']);
    $respuesta = mysqli_query($conexion, "select nombre from usuarios where nombre='$nombre'");
    $cantidad = mysqli_num_rows($respuesta);
    if ($cantidad == 1)
      echo '{"resultado":"repetido"}';
    else
      echo '{"resultado":"norepetido"}';
    break;
}

?>

Continuando con el contenido del archivo 'login.html', cuando el usuario ingresa sus datos en el formulario de 'login' y presiona el botón 'Ingresar':

      $('#BotonLogin').click(function () {
        let usuario = retornarUsuario();
        loginUsuario(usuario);
      });

Se llama a la función 'loginUsuario' con los datos ingresados en el formulario:

      function loginUsuario(usuario) {
        $.ajax({
          type: 'POST',
          url: 'login.php',
          data: usuario,
          success: function (respuesta) {
            if (respuesta == 'correcta') {
              window.location = 'index.php';
            }
            else
              alert('nombre de usuario o clave incorrecta');
          },
          error: function () {
            alert('Error');
          }
        });
      }

La función loginUsuario procede mediante una llamada AJAX a verificar la existencia del nombre de usuario y su clave.

En el servidor el archivo 'login.php' se encarga de controlar la existencia del nombre de usuario y clave ingresada.

login.php
<?php
require("conexion.php");

$conexion = retornarConexion();

$usuario = mysqli_real_escape_string($conexion, $_POST['usuario']);
$clave = mysqli_real_escape_string($conexion, $_POST['clave']);
$respuesta = mysqli_query($conexion, "select nombre,clave from usuarios where nombre='$usuario' and clave='$clave'");
if (mysqli_num_rows($respuesta) == 1) {
    session_start();
    $_SESSION['usuario'] = $usuario;
    echo "correcta";
} else {
    echo "incorrecta";
}
?>

Creamos una variable de sesión, recordando llamar primero a la función session_start():

    session_start();
    $_SESSION['usuario'] = $usuario;

Como vemos si se ha ingresado un nombre de usuario y clave existente procedemos a retornar un string con la cadena "correcta".

En el navegador controlamos el string devuelto para redireccionar a la página principal del calendario de eventos:

          success: function (respuesta) {
            if (respuesta == 'correcta') {
              window.location = 'index.php';
            }