sql >> Base de Datos >  >> RDS >> Mysql

Gestión de cuentas de usuario, roles, permisos, autenticación PHP y MySQL - Parte 3

Esta es la parte 3 de una serie de tutoriales sobre cómo crear un sistema de administración de cuentas de usuario. Puedes encontrar las otras partes aquí: parte 1, parte 2.

Validación de formulario

En este punto de la página signup.php, si simplemente hace clic en el botón de registro sin completar ninguno de los campos del formulario, no recibe ningún comentario, pero el formulario tampoco hace nada. Solo se queda ahí mirándote. Permanece así porque hay errores en $errors de nuestra función validateUser() que definimos anteriormente y que aún no mostramos en el formulario. Estos errores existen en pares clave-valor.

Por ejemplo, $errors['username'] contiene el error, si lo hay, para el campo de nombre de usuario. Entonces podemos verificar si existe el error de nombre de usuario y luego agregamos la clase de arranque tiene error al elemento div que envuelve el campo de entrada del nombre de usuario. Esto hace que el texto de la etiqueta y el borde de entrada sean de color rojo, lo que indica que hay un error.

Validaremos los campos de nombre de usuario, correo electrónico, contraseña y confirmación de contraseña. Así que abra su archivo signup.php y reemplace estos cuatro campos con este código:

<div class="form-group <?php echo isset($errors['username']) ? 'has-error' : '' ?>">
  <label class="control-label">Username</label>
  <input type="text" name="username" value="<?php echo $username; ?>" class="form-control">
  <?php if (isset($errors['username'])): ?>
    <span class="help-block"><?php echo $errors['username'] ?></span>
  <?php endif; ?>
</div>
<div class="form-group <?php echo isset($errors['email']) ? 'has-error' : '' ?>">
  <label class="control-label">Email Address</label>
  <input type="email" name="email" value="<?php echo $email; ?>" class="form-control">
  <?php if (isset($errors['email'])): ?>
    <span class="help-block"><?php echo $errors['email'] ?></span>
  <?php endif; ?>
</div>
<div class="form-group <?php echo isset($errors['password']) ? 'has-error' : '' ?>">
  <label class="control-label">Password</label>
  <input type="password" name="password" class="form-control">
  <?php if (isset($errors['password'])): ?>
    <span class="help-block"><?php echo $errors['password'] ?></span>
  <?php endif; ?>
</div>
<div class="form-group <?php echo isset($errors['passwordConf']) ? 'has-error' : '' ?>">
  <label class="control-label">Password confirmation</label>
  <input type="password" name="passwordConf" class="form-control">
  <?php if (isset($errors['passwordConf'])): ?>
    <span class="help-block"><?php echo $errors['passwordConf'] ?></span>
  <?php endif; ?>
</div>

Justo debajo de cada campo de entrada, mostramos condicionalmente el mensaje de error para cada campo de formulario.

En caso de que no supieras sobre el operador ternario, aquí tienes una breve explicación.

<?php echo isset($errors['username']) ? 'has-error' : '' ?>

Esta declaración básicamente dice que si la variable $errors['username'] se establece en un valor (no está vacía), se muestra un error; de lo contrario, se muestra una cadena vacía. Básicamente es solo una declaración if-else.

Ahora puedes probar esta validación haciendo clic en el formulario vacío. Verá mensajes de validación con un buen formato.

Inicio de sesión de usuario

En la carpeta raíz de su aplicación, cree un archivo llamado login.php.

iniciar sesión.php:

<?php include('config.php'); ?>
<?php include(INCLUDE_PATH . '/logic/userSignup.php'); ?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>UserAccounts - Login</title>
  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
  <!-- Custome styles -->
  <link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
  <?php include(INCLUDE_PATH . "/layouts/navbar.php") ?>
  <div class="container">
    <div class="row">
      <div class="col-md-4 col-md-offset-4">
        <form class="form" action="login.php" method="post">
          <h2 class="text-center">Login</h2>
          <hr>
          <!-- display form error messages  -->
          <?php include(INCLUDE_PATH . "/layouts/messages.php") ?>
          <div class="form-group <?php echo isset($errors['username']) ? 'has-error' : '' ?>">
            <label class="control-label">Username or Email</label>
            <input type="text" name="username" id="password" value="<?php echo $username; ?>" class="form-control">
            <?php if (isset($errors['username'])): ?>
              <span class="help-block"><?php echo $errors['username'] ?></span>
            <?php endif; ?>
          </div>
          <div class="form-group <?php echo isset($errors['password']) ? 'has-error' : '' ?>">
            <label class="control-label">Password</label>
            <input type="password" name="password" id="password" class="form-control">
            <?php if (isset($errors['password'])): ?>
              <span class="help-block"><?php echo $errors['password'] ?></span>
            <?php endif; ?>
          </div>
          <div class="form-group">
            <button type="submit" name="login_btn" class="btn btn-success">Login</button>
          </div>
          <p>Don't have an account? <a href="signup.php">Sign up</a></p>
        </form>
      </div>
    </div>
  </div>
<?php include(INCLUDE_PATH . "/layouts/footer.php") ?>

Ahora abra userSignup.php y al final del archivo, agregue este código para iniciar sesión como usuario:

// ...

// USER LOGIN
if (isset($_POST['login_btn'])) {
	// validate form values
	$errors = validateUser($_POST, ['login_btn']);
	$username = $_POST['username'];
	$password = $_POST['password']; // don't escape passwords.

	if (empty($errors)) {
		$sql = "SELECT * FROM users WHERE username=? OR email=? LIMIT 1";
		$user = getSingleRecord($sql, 'ss', [$username, $username]);

		if (!empty($user)) { // if user was found
			if (password_verify($password, $user['password'])) { // if password matches
				// log user in
				loginById($user['id']);
			} else { // if password does not match
				$_SESSION['error_msg'] = "Wrong credentials";
			}
		} else { // if no user found
			$_SESSION['error_msg'] = "Wrong credentials";
		}
	}
}

Si hace clic en el botón de inicio de sesión sin completarlo, aparecerán mensajes de validación en el formulario al igual que en el caso de la página de registro.

Ahora ingrese el correo electrónico y la contraseña de la cuenta de usuario que creamos anteriormente y haga clic en el botón de inicio de sesión. Si las credenciales eran correctas, iniciará sesión y será redirigido a la página de inicio. Aparecerá un mensaje flash que le indicará que ha iniciado sesión. 

Pero notará que aunque el usuario ahora haya iniciado sesión, los enlaces de registro e inicio de sesión en la barra de navegación aún se muestran, lo que no tiene sentido, ¿verdad? Vamos a reemplazarlos con el nombre de usuario registrado y un menú desplegable con un enlace de cierre de sesión.

Abra el archivo navbar.php y reemplace el código que contiene con este:

barra de navegación.php:

<!-- the whole site is wrapped in a container div to give it some margin on the sides -->
<!-- closing container div can be found in the footer -->
<div class="container">
  <nav class="navbar navbar-default">
    <div class="container-fluid">
      <div class="navbar-header">
        <a class="navbar-brand" href="#">UserAccounts</a>
      </div>
      <!-- <ul class="nav navbar-nav">
        <li class="active"><a href="#">Home</a></li>
        <li><a href="#">Page 1</a></li>
        <li><a href="#">Page 2</a></li>
      </ul> -->
      <ul class="nav navbar-nav navbar-right">
        <?php if (isset($_SESSION['user'])): ?>
          <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
              <?php echo $_SESSION['user']['username'] ?> <span class="caret"></span></a>

              <?php if (isAdmin($_SESSION['user']['id'])): ?>
                <ul class="dropdown-menu">
                  <li><a href="<?php echo BASE_URL . 'admin/profile.php' ?>">Profile</a></li>
                  <li><a href="<?php echo BASE_URL . 'admin/dashboard.php' ?>">Dashboard</a></li>
                  <li role="separator" class="divider"></li>
                  <li><a href="<?php echo BASE_URL . 'logout.php' ?>" style="color: red;">Logout</a></li>
                </ul>
              <?php else: ?>
                <ul class="dropdown-menu">
                  <li><a href="<?php echo BASE_URL . 'logout.php' ?>" style="color: red;">Logout</a></li>
                </ul>
              <?php endif; ?>
          </li>
        <?php else: ?>
          <li><a href="<?php echo BASE_URL . 'signup.php' ?>"><span class="glyphicon glyphicon-user"></span> Sign Up</a></li>
          <li><a href="<?php echo BASE_URL . 'login.php' ?>"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
        <?php endif; ?>
      </ul>
    </div>
  </nav>

Ahora actualice la página index.php. Si aún estaba conectado, verá que el encabezado ha cambiado y ahora muestra su nombre de usuario en la barra de navegación. Cuando haga clic en el nombre de usuario, aparecerá un menú desplegable con un enlace para cerrar sesión. Si hace clic en él, dirá página no encontrada porque aún no hemos creado el archivo logout.php. Vamos a crear ese archivo ahora en la carpeta raíz de nuestra aplicación.

cerrar sesión.php: 

<?php
  session_start();
  session_destroy();
  unset($_SESSION['user']);
  header("location: login.php");
?>

Y hemos terminado con la autenticación de usuario normal. Ahora pasamos al quid de la cuestión, que es la sección de administración. Espero que lo estés disfrutando.

En este momento estamos iniciando la sesión del usuario a través de una sola función, la función loginById(). En esa función, si se descubre que el usuario que está iniciando sesión es un usuario administrativo, se le redirige al archivo dashboard.php.

Sección de administración

Dentro de la carpeta de administración, cree el archivo dashboard.php:

tablero.php:

<?php include('../config.php') ?>
<?php include(ROOT_PATH . '/admin/middleware.php') ?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Admin</title>
  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
  <!-- Custome styles -->
  <link rel="stylesheet" href="../static/css/style.css">
</head>
<body>
  <?php include(INCLUDE_PATH . "/layouts/admin_navbar.php") ?>

  <div class="col-md-4 col-md-offset-4">
      <h1 class="text-center">Admin</h1>
      <br />
      <ul class="list-group">
        <a href="<?php echo BASE_URL . 'admin/posts/postList.php' ?>" class="list-group-item">Manage Posts</a>
        <a href="<?php echo BASE_URL . 'admin/users/userList.php' ?>" class="list-group-item">Manage Users</a>
        <a href="<?php echo BASE_URL . 'admin/roles/roleList.php' ?>" class="list-group-item">Manage Roles</a>
      </ul>
  </div>
  <?php include(INCLUDE_PATH . "/layouts/footer.php") ?>
</body>
</html>

En su navegador, visite http://localhost/user-accounts/admin/dashboard.php y verá algunos mensajes de advertencia. Esto se debe a que incluimos dos archivos que aún no existen:middleware.php y admin_navbar.php.

En cuanto a middleware.php, trabajaremos en ello más adelante. Pero por ahora solo créalo dentro de la carpeta de administración y déjalo en blanco para que el mensaje de advertencia desaparezca y nos deje en paz.

En cuanto a admin_navbar.php, créelo dentro de la carpeta includes/layouts :

admin_navbar.php:

<!-- the whole site is wrapped in a container div to give it some margin on the sides -->
<!-- closing container div can be found in the footer -->
<div class="container">
  <nav class="navbar navbar-inverse">
    <div class="container-fluid">
      <div class="navbar-header">
        <a class="navbar-brand" href="<?php echo BASE_URL . 'admin/dashboard.php' ?>">Dashboard</a>
      </div>
      <ul class="nav navbar-nav navbar-right">
        <?php if (isset($_SESSION['user'])): ?>
          <li><a href="<?php echo BASE_URL . 'index.php' ?>"><span class="glyphicon glyphicon-globe"></span></a></li>
          <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
              <?php echo $_SESSION['user']['username'] . ' (' . $_SESSION['user']['role'] . ')'; ?> <span class="caret"></span></a>
            <ul class="dropdown-menu">
              <li><a href="<?php echo BASE_URL . 'admin/users/editProfile.php' ?>">Profile</a></li>
              <li><a href="<?php echo BASE_URL . 'admin/dashboard.php' ?>">Dashboard</a></li>
              <li role="separator" class="divider"></li>
              <li><a href="<?php echo BASE_URL . 'logout.php' ?>" style="color: red;">Logout</a></li>
            </ul>
          </li>
        <?php endif; ?>
      </ul>
    </div>
  </nav>
  <?php include(INCLUDE_PATH . "/layouts/messages.php") ?>

En su navegador, actualice la página dashboard.php ahora y los mensajes de advertencia desaparecerán.

El dashboard.php es el área de administración, ¿verdad? Se supone que no debe ser accedido por usuarios comunes. Por lo tanto, debemos redirigir a cualquier usuario normal que intente visitar esta página a la página de inicio. Además, todavía no estamos creando/administrando usuarios y roles administradores. Todo eso llegará pronto.

Vamos a terminar esta parte aquí. En la siguiente parte, procedemos a administrar las cuentas de usuario administrador y también al control de acceso.

Si está disfrutando de estos tutoriales y quiere más, considere compartir/recomendar los tutoriales entre sus amigos. Eso me ayudará mucho a crear más de esto.

Gracias por seguirnos y nos vemos en la siguiente parte.