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

Système de réinitialisation de mot de passe en PHP

Une caractéristique très importante de tout bon site Web d'adhésion est un système de réinitialisation du mot de passe, car certains utilisateurs risquent d'oublier leur mot de passe. Dans ce didacticiel, je décris les étapes nécessaires à la récupération du mot de passe d'un utilisateur ; nous allons également implémenter un tel système en utilisant PHP et une base de données MySQL dans ce tutoriel.

L'ensemble du processus de mise en œuvre d'un tel système peut être décomposé en 3 étapes principales. Pour faciliter l'explication, analysons ces étapes au regard des formulaires que nous allons présenter à l'utilisateur à remplir :

  1. Formulaire de connexion :  Ce formulaire prend la combinaison du nom d'utilisateur et du mot de passe d'un utilisateur et le connecte s'il est enregistré sur le système. Sur ce formulaire, nous fournissons un "Mot de passe oublié?" lien au cas où l'utilisateur aurait oublié son mot de passe et aurait besoin de le réinitialiser.
  2. Formulaire d'e-mail :  Si l'utilisateur a oublié son mot de passe, il peut cliquer sur le lien « Mot de passe oublié ? lien sur la page de connexion pour le réinitialiser. En cliquant sur ce lien, ils seront redirigés vers une autre page qui les invitera à saisir l'adresse e-mail. Lorsque l'adresse e-mail qu'ils fournissent ne figure pas dans notre table d'utilisateurs dans la base de données, nous afficherons un message d'erreur indiquant "Aucun utilisateur de ce type n'existe sur notre système". Si, par contre, l'utilisateur existe, nous générerons un jeton unique (une chaîne aléatoire unique) et stockerons ce jeton avec cette adresse e-mail dans la table password_resets de la base de données. Ensuite, nous leur enverrons un e-mail contenant ce jeton dans un lien. Lorsqu'ils cliquent sur le lien dans l'e-mail que nous leur avons envoyé, ils sont renvoyés vers notre site Web sur une page qui leur présente un autre formulaire.
  3. Formulaire de nouveau mot de passe :  Une fois que l'utilisateur est de retour sur notre site Web, nous récupérons le jeton provenant du lien et le stockons dans une variable de session. Ensuite, nous leur présenterons un formulaire qui leur demandera d'entrer un nouveau mot de passe pour leur compte sur notre site Web. Lorsque le nouveau mot de passe est soumis, nous interrogeons la table password_resets pour l'enregistrement contenant ce jeton qui vient de sortir du lien dans le courrier. Si le jeton se trouve dans la table password_resets, nous sommes convaincus que l'utilisateur est qui il est et qu'il a cliqué sur le lien dans son courrier. À ce stade, nous récupérons l'e-mail de l'utilisateur dans la table password_resets (rappelez-vous que nous avions enregistré le jeton à côté de son adresse e-mail) et utilisons cet e-mail pour récupérer l'utilisateur dans la table des utilisateurs et mettre à jour son mot de passe.

J'espère que c'est assez clair. Si ce n'est pas le cas, restez dans les parages et cela deviendra plus clair au fur et à mesure de la mise en œuvre.

Mise en œuvre

Créez une base de données appelée password_recovery et dans cette base de données, créez deux tables, à savoir les utilisateurs et les réinitialisations de mot de passe avec les champs suivants :

utilisateurs :

+----+-----------+--------------+------------+
|     field      |     type     | specs      |
+----+-----------+--------------+------------+
|  id            | INT(11)      |            |
|  username      | VARCHAR(255) |            |
|  email         | VARCHAR(255) | UNIQUE     |
|  password      | VARCHAR(255) |            |
+----------------+--------------+------------+

password_reset :

+----+-----------+--------------+------------+
|     field      |     type     | specs      |
+----+-----------+--------------+------------+
|  id            | INT(11)      |            |
|  email         | VARCHAR(255) |            |
|  token         | VARCHAR(255) | UNIQUE     |
+----------------+--------------+------------+

Remarque : Cette application nécessite que l'utilisateur soit déjà enregistré sur le système. Mais, nous ne couvrirons pas la partie d'enregistrement des utilisateurs dans ce tutoriel car elle a déjà été couverte sur ce site. Vous pouvez d'abord suivre ce didacticiel (je vous le recommande) ou non, mais gardez à l'esprit que nous devons avoir un utilisateur dans notre table d'utilisateurs dans la base de données avant de pouvoir procéder à la réinitialisation de son mot de passe. Donc, d'une manière ou d'une autre, ajoutez un utilisateur à votre base de données mysql. Vous pouvez utiliser un outil comme PHPMyAdmin et vous assurer de chiffrer le mot de passe à l'aide de md5().

Créez maintenant un dossier de projet appelé password-recovery et assurez-vous que ce dossier se trouve dans le répertoire de votre serveur (dossier htdocs ou dossier www). Dans ce dossier, créez trois fichiers à savoir :login.php, enter_email.php, new_pass.php :

Chacun de ces trois fichiers représente les trois étapes décrites précédemment. Ouvrez chacun d'eux et collez-y les codes suivants :

login.php :

<?php include('app_logic.php'); ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Password Reset PHP</title>
	<link rel="stylesheet" href="main.css">
</head>
<body>
	<form class="login-form" action="login.php" method="post">
		<h2 class="form-title">Login</h2>
		<!-- form validation messages -->
		<?php include('messages.php'); ?>
		<div class="form-group">
			<label>Username or Email</label>
			<input type="text" value="<?php echo $user_id; ?>" name="user_id">
		</div>
		<div class="form-group">
			<label>Password</label>
			<input type="password" name="password">
		</div>
		<div class="form-group">
			<button type="submit" name="login_user" class="login-btn">Login</button>
		</div>
		<p><a href="enter_email.php">Forgot your password?</a></p>
	</form>
</body>
</html>

enter_email.php :

<?php include('app_logic.php'); ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Password Reset PHP</title>
	<link rel="stylesheet" href="main.css">
</head>
<body>
	<form class="login-form" action="enter_email.php" method="post">
		<h2 class="form-title">Reset password</h2>
		<!-- form validation messages -->
		<?php include('messages.php'); ?>
		<div class="form-group">
			<label>Your email address</label>
			<input type="email" name="email">
		</div>
		<div class="form-group">
			<button type="submit" name="reset-password" class="login-btn">Submit</button>
		</div>
	</form>
</body>
</html>

new_pass.php :

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Password Reset PHP</title>
	<link rel="stylesheet" href="main.css">
</head>
<body>
	<form class="login-form" action="new_password.php" method="post">
		<h2 class="form-title">New password</h2>
		<!-- form validation messages -->
		<?php include('messages.php'); ?>
		<div class="form-group">
			<label>New password</label>
			<input type="password" name="new_pass">
		</div>
		<div class="form-group">
			<label>Confirm new password</label>
			<input type="password" name="new_pass_c">
		</div>
		<div class="form-group">
			<button type="submit" name="new_password" class="login-btn">Submit</button>
		</div>
	</form>
</body>
</html>

Dans chacun de ces fichiers, vous voyez que nous incluons trois fichiers que nous n'avons pas encore créés, à savoir app_logic.php , messages.php, file et main.css. Le premier gère toute la logique de notre application, comme l'interrogation de la base de données, l'envoi d'e-mails à l'utilisateur, etc. ; le second affiche des messages de rétroaction à l'utilisateur, par exemple lorsqu'il entre un mauvais e-mail, le troisième est le style de l'application.

Créez ces fichiers dans le dossier de récupération de mot de passe. Dans le fichier main.css, ajoutez ce code de style :

principal.css :

body {
	background: #3b5998;
	font-size: 1.1em;
	font-family: sans-serif;
}
a {
	text-decoration: none;
}
form {
	width: 25%;
	margin: 70px auto;
	background: white;
	padding: 10px;
	border-radius: 3px;
}
h2.form-title {
	text-align: center;
}
input {
	display: block;
	box-sizing: border-box;
	width: 100%;
	padding: 8px;
}
form .form-group {
	margin: 10px auto;
}
form button {
	width: 100%;
	border: none;
	color: white;
	background: #3b5998;
	padding: 15px;
	border-radius: 5px;
}
.msg {
	margin: 5px auto;
	border-radius: 5px;
	border: 1px solid red;
	background: pink;
	text-align: left;
	color: brown;
	padding: 10px;
}

app_logic.php :

<?php 

session_start();
$errors = [];
$user_id = "";
// connect to database
$db = mysqli_connect('localhost', 'root', '', 'password-reset-php');

// LOG USER IN
if (isset($_POST['login_user'])) {
  // Get username and password from login form
  $user_id = mysqli_real_escape_string($db, $_POST['user_id']);
  $password = mysqli_real_escape_string($db, $_POST['password']);
  // validate form
  if (empty($user_id)) array_push($errors, "Username or Email is required");
  if (empty($password)) array_push($errors, "Password is required");

  // if no error in form, log user in
  if (count($errors) == 0) {
    $password = md5($password);
    $sql = "SELECT * FROM users WHERE username='$user_id' OR email='$user_id' AND password='$password'";
    $results = mysqli_query($db, $sql);

    if (mysqli_num_rows($results) == 1) {
      $_SESSION['username'] = $user_id;
      $_SESSION['success'] = "You are now logged in";
      header('location: index.php');
    }else {
      array_push($errors, "Wrong credentials");
    }
  }
}

/*
  Accept email of user whose password is to be reset
  Send email to user to reset their password
*/
if (isset($_POST['reset-password'])) {
  $email = mysqli_real_escape_string($db, $_POST['email']);
  // ensure that the user exists on our system
  $query = "SELECT email FROM users WHERE email='$email'";
  $results = mysqli_query($db, $query);

  if (empty($email)) {
    array_push($errors, "Your email is required");
  }else if(mysqli_num_rows($results) <= 0) {
    array_push($errors, "Sorry, no user exists on our system with that email");
  }
  // generate a unique random token of length 100
  $token = bin2hex(random_bytes(50));

  if (count($errors) == 0) {
    // store token in the password-reset database table against the user's email
    $sql = "INSERT INTO password_reset(email, token) VALUES ('$email', '$token')";
    $results = mysqli_query($db, $sql);

    // Send email to user with the token in a link they can click on
    $to = $email;
    $subject = "Reset your password on examplesite.com";
    $msg = "Hi there, click on this <a href=\"new_password.php?token=" . $token . "\">link</a> to reset your password on our site";
    $msg = wordwrap($msg,70);
    $headers = "From: [email protected]";
    mail($to, $subject, $msg, $headers);
    header('location: pending.php?email=' . $email);
  }
}

// ENTER A NEW PASSWORD
if (isset($_POST['new_password'])) {
  $new_pass = mysqli_real_escape_string($db, $_POST['new_pass']);
  $new_pass_c = mysqli_real_escape_string($db, $_POST['new_pass_c']);

  // Grab to token that came from the email link
  $token = $_SESSION['token'];
  if (empty($new_pass) || empty($new_pass_c)) array_push($errors, "Password is required");
  if ($new_pass !== $new_pass_c) array_push($errors, "Password do not match");
  if (count($errors) == 0) {
    // select email address of user from the password_reset table 
    $sql = "SELECT email FROM password_reset WHERE token='$token' LIMIT 1";
    $results = mysqli_query($db, $sql);
    $email = mysqli_fetch_assoc($results)['email'];

    if ($email) {
      $new_pass = md5($new_pass);
      $sql = "UPDATE users SET password='$new_pass' WHERE email='$email'";
      $results = mysqli_query($db, $sql);
      header('location: index.php');
    }
  }
}
?>

Ici, vous voyez trois blocs d'instructions if. Ces déclarations gèrent trois actions, à savoir la connexion de l'utilisateur, la réception d'un e-mail de réinitialisation et la réception d'un nouveau mot de passe. Dans le deuxième bloc, après avoir reçu l'adresse e-mail de l'utilisateur, l'utilisateur est redirigé vers une page pending.php. Cette page affiche simplement un message indiquant à l'utilisateur qu'un e-mail a été envoyé à son adresse e-mail qu'il peut utiliser pour réinitialiser son mot de passe.

Créez pending.php dans le dossier racine de notre projet et ajoutez ce code à l'intérieur :

en attente.php :

<?php include('app_logic.php'); ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Password Reset PHP</title>
	<link rel="stylesheet" href="main.css">
</head>
<body>

	<form class="login-form" action="login.php" method="post" style="text-align: center;">
		<p>
			We sent an email to  <b><?php echo $_GET['email'] ?></b> to help you recover your account. 
		</p>
	    <p>Please login into your email account and click on the link we sent to reset your password</p>
	</form>
		
</body>
</html>

messages.php est un fichier contenant l'extrait de code permettant d'afficher les messages d'erreur sur le formulaire. Ouvrez-le et collez-y ce code :

messages.php :

<?php  if (count($errors) > 0) : ?>
  <div class="msg">
  	<?php foreach ($errors as $error) : ?>
  	  <span><?php echo $error ?></span>
  	<?php endforeach ?>
  </div>
<?php  endif ?>

Ouvrez maintenant ce projet sur votre navigateur à http://localhost/password-recovery/login.php et jouez avec.

Remarque : Nous avons utilisé la fonction mail() de PHP pour envoyer un e-mail à l'utilisateur. Cette fonction ne peut pas envoyer de mails depuis localhost. Il ne peut le faire qu'en utilisant un serveur hébergé sur Internet. Cependant, nous pouvons utiliser une application de test de messagerie pour simuler l'envoi d'e-mails si vous souhaitez avoir une démo sur votre système local.

Conclusion

Merci d'avoir suivi ce tuto jusqu'au bout. J'espère que l'explication a été suffisamment claire et que vous avez appris quelque chose qui peut vous être utile dans votre développement Web. Si vous avez des problèmes ou des préoccupations, n'oubliez pas de les laisser dans les commentaires ci-dessous et je vous répondrai.

Bonne journée !