Mysql
 sql >> Base de données >  >> RDS >> Mysql

Gestion des comptes utilisateurs, rôles, permissions, authentification PHP et MySQL - Partie 3

Il s'agit de la troisième partie d'une série de tutoriels sur la création d'un système de gestion des comptes d'utilisateurs. Vous pouvez trouver les autres parties ici : partie 1, partie 2.

Validation du formulaire

À ce stade de la page signup.php, si vous cliquez simplement sur le bouton d'inscription sans remplir aucun des champs du formulaire, vous n'obtenez aucun commentaire, mais le formulaire ne fait rien non plus. Il reste juste là à vous regarder. Cela reste comme ça parce qu'il y a des erreurs dans un $errors de notre fonction validateUser() que nous avons défini précédemment que nous n'affichons pas encore sur le formulaire. Ces erreurs existent dans les paires clé-valeur.

Par exemple, $errors['username'] contient l'erreur, le cas échéant, pour le champ de nom d'utilisateur. Ainsi, nous pouvons vérifier si l'erreur de nom d'utilisateur existe, puis nous ajoutons la classe bootstrap has-error à l'élément div qui enveloppe le champ de saisie du nom d'utilisateur. Cela rend le texte de l'étiquette et la bordure de saisie de couleur rouge indiquant qu'il y a une erreur.

Nous validerons les champs de nom d'utilisateur, d'adresse e-mail, de mot de passe et de confirmation du mot de passe. Ouvrez donc votre fichier signup.php et remplacez ces quatre champs par ce code :

<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>

Juste en dessous de chaque champ de saisie, nous affichons conditionnellement le message d'erreur pour chaque champ de formulaire.

Juste au cas où vous ne connaissiez pas l'opérateur ternaire, voici une brève explication.

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

Cette déclaration indique essentiellement que si la variable $errors['username'] est définie sur une valeur (n'est pas vide), affiche has-error, sinon affiche une chaîne vide. Il s'agit essentiellement d'une simple instruction if-else.

Vous pouvez maintenant essayer cette validation en cliquant sur le formulaire vide. Vous verrez de jolis messages de validation formatés.

Connexion utilisateur

Dans le dossier racine de votre application, créez un fichier nommé login.php.

login.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") ?>

Ouvrez maintenant userSignup.php et à la fin du fichier, ajoutez ce code pour vous connecter :

// ...

// 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 vous cliquez sur le bouton de connexion sans le remplir, des messages de validation apparaîtront sur le formulaire comme dans le cas de la page d'inscription.

Entrez maintenant l'e-mail et le mot de passe du compte utilisateur que nous avons créé précédemment et cliquez sur le bouton de connexion. Si les informations d'identification étaient correctes, vous serez connecté et redirigé vers la page d'accueil. Un message flash s'affichera pour vous indiquer que vous êtes maintenant connecté. 

Mais vous remarquerez que même si l'utilisateur est maintenant connecté, les liens d'inscription et de connexion dans la barre de navigation sont toujours affichés, ce qui n'a aucun sens, n'est-ce pas ? Remplaçons-les par le nom d'utilisateur connecté et une liste déroulante avec un lien de déconnexion.

Ouvrez le fichier navbar.php et remplacez le code qui s'y trouve avec celui-ci :

barre de navigation.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>

Actualisez maintenant la page index.php. Si vous étiez toujours connecté, vous verrez que l'en-tête a changé et affiche maintenant votre nom d'utilisateur sur la barre de navigation. Lorsque vous cliquez sur le nom d'utilisateur, une liste déroulante apparaît avec un lien de déconnexion. Si vous cliquez dessus, il indiquera page introuvable car nous n'avons pas encore créé le fichier logout.php. Créons maintenant ce fichier dans le dossier racine de notre application.

logout.php : 

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

Et nous en avons fini avec l'authentification normale de l'utilisateur. Nous passons maintenant au cœur du problème, à savoir la section d'administration. J'espère que vous l'apprécierez.

À l'heure actuelle, nous connectons l'utilisateur via une seule fonction, la fonction loginById(). Dans cette fonction, si l'utilisateur qui se connecte s'avère être un utilisateur administratif, il est redirigé vers le fichier dashboard.php.

Section d'administration

Dans le dossier admin, créez le fichier dashboard.php :

tableau de bord.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>

Sur votre navigateur, visitez http://localhost/user-accounts/admin/dashboard.php et vous verrez des messages d'avertissement. C'est parce que nous incluons deux fichiers qui n'existent pas encore :middleware.php et admin_navbar.php.

Quant à middleware.php, nous y travaillerons plus tard. Mais pour l'instant, créez-le simplement dans le dossier admin et laissez-le vide afin que le message d'avertissement puisse disparaître et nous laisser en paix.

Quant au fichier admin_navbar.php, créez-le dans le dossier 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") ?>

Sur votre navigateur, actualisez la page dashboard.php maintenant et les messages d'avertissement ont disparu.

Le dashboard.php est la zone d'administration, n'est-ce pas ? Il n'est pas censé être accessible aux utilisateurs ordinaires. Nous devons donc rediriger tout utilisateur normal essayant de visiter cette page vers la page d'accueil. De plus, nous ne créons/gérons pas encore les utilisateurs et les rôles d'administrateur. Tout cela arrive bientôt.

Terminons cette partie ici. Dans la partie suivante, nous procédons à la gestion des comptes d'utilisateurs administrateur ainsi qu'au contrôle d'accès.

Si vous appréciez ces tutoriels et que vous en voulez plus, pensez à partager/recommander les tutoriels à vos amis. Cela contribuera grandement à m'aider à en créer davantage.

Merci d'avoir suivi et à bientôt dans la prochaine partie.