TUTO PHP - Mot de passe oublié ?

PrimFX Boris ('PrimFX') Le 29 novembre 2015

Je vous propose de voir comment créer un système de récupération de mot de passe en PHP ! Je sais, le tuto est assez long, mais le résultat est sympa (je trouve) 😛

Quelques liens utiles:
- Envoyer des mails en PHP
- Créer un espace membre en PHP #1

Code PHP du tuto:
<?php
session_start();

if(isset($_POST['recup_submit'],$_POST['recup_mail'])) {
   if(!empty($_POST['recup_mail'])) {
      $recup_mail = htmlspecialchars($_POST['recup_mail']);
      if(filter_var($recup_mail,FILTER_VALIDATE_EMAIL)) {
         $mailexist = $bdd->prepare('SELECT id,pseudo FROM membres WHERE mail = ?');
         $mailexist->execute(array($recup_mail));
         $mailexist_count = $mailexist->rowCount();
         if($mailexist_count == 1) {
            $pseudo = $mailexist->fetch();
            $pseudo = $pseudo['pseudo'];
            
            $_SESSION['recup_mail'] = $recup_mail;
            $recup_code = "";
            for($i=0; $i < 8; $i++) { 
               $recup_code .= mt_rand(0,9);
            }
            $mail_recup_exist = $bdd->prepare('SELECT id FROM recuperation WHERE mail = ?');
            $mail_recup_exist->execute(array($recup_mail));
            $mail_recup_exist = $mail_recup_exist->rowCount();
            if($mail_recup_exist == 1) {
               $recup_insert = $bdd->prepare('UPDATE recuperation SET code = ? WHERE mail = ?');
               $recup_insert->execute(array($recup_code,$recup_mail));
            } else {
               $recup_insert = $bdd->prepare('INSERT INTO recuperation(mail,code) VALUES (?, ?)');
               $recup_insert->execute(array($recup_mail,$recup_code));
            }
            $header="MIME-Version: 1.0\r\n";
         $header.='From:"[VOUS]"<votremail@mail.com>'."\n";
         $header.='Content-Type:text/html; charset="utf-8"'."\n";
         $header.='Content-Transfer-Encoding: 8bit';
         $message = '
         <html>
         <head>
           <title>Récupération de mot de passe - Votresite</title>
           <meta charset="utf-8" />
         </head>
         <body>
           <font color="#303030";>
             <div align="center">
               <table width="600px">
                 <tr>
                   <td>
                     
                     <div align="center">Bonjour <b>'.$pseudo.'</b>,</div>
                     Voici votre code de récupération: <b>'.$recup_code.'</b>
                     A bientôt sur <a href="#">Votre site</a> !
                     
                   </td>
                 </tr>
                 <tr>
                   <td align="center">
                     <font size="2">
                       Ceci est un email automatique, merci de ne pas y répondre
                     </font>
                   </td>
                 </tr>
               </table>
             </div>
           </font>
         </body>
         </html>
         ';
         mail($recup_mail, "Récupération de mot de passe - Votresite", $message, $header);
            header("Location:http://127.0.0.1/path/recuperation.php?section=code");
         } else {
            $error = "Cette adresse mail n'est pas enregistrée";
         }
      } else {
         $error = "Adresse mail invalide";
      }
   } else {
      $error = "Veuillez entrer votre adresse mail";
   }
}
if(isset($_POST['verif_submit'],$_POST['verif_code'])) {
   if(!empty($_POST['verif_code'])) {
      $verif_code = htmlspecialchars($_POST['verif_code']);
      $verif_req = $bdd->prepare('SELECT id FROM recuperation WHERE mail = ? AND code = ?');
      $verif_req->execute(array($_SESSION['recup_mail'],$verif_code));
      $verif_req = $verif_req->rowCount();
      if($verif_req == 1) {
         $up_req = $bdd->prepare('UPDATE recuperation SET confirme = 1 WHERE mail = ?');
         $up_req->execute(array($_SESSION['recup_mail']));
         header('Location:http://127.0.0.1/path/recuperation.php?section=changemdp');
      } else {
         $error = "Code invalide";
      }
   } else {
      $error = "Veuillez entrer votre code de confirmation";
   }
}
if(isset($_POST['change_submit'])) {
   if(isset($_POST['change_mdp'],$_POST['change_mdpc'])) {
      $verif_confirme = $bdd->prepare('SELECT confirme FROM recuperation WHERE mail = ?');
      $verif_confirme->execute(array($_SESSION['recup_mail']));
      $verif_confirme = $verif_confirme->fetch();
      $verif_confirme = $verif_confirme['confirme'];
      if($verif_confirme == 1) {
         $mdp = htmlspecialchars($_POST['change_mdp']);
         $mdpc = htmlspecialchars($_POST['change_mdpc']);
         if(!empty($mdp) AND !empty($mdpc)) {
            if($mdp == $mdpc) {
               $mdp = sha1($mdp);
               $ins_mdp = $bdd->prepare('UPDATE membres SET motdepasse = ? WHERE mail = ?');
               $ins_mdp->execute(array($mdp,$_SESSION['recup_mail']));
              $del_req = $bdd->prepare('DELETE FROM recuperation WHERE mail = ?');
              $del_req->execute(array($_SESSION['recup_mail']));
               header('Location:http://127.0.0.1/path/connexion/');
            } else {
               $error = "Vos mots de passes ne correspondent pas";
            }
         } else {
            $error = "Veuillez remplir tous les champs";
         }
      } else {
         $error = "Veuillez valider votre mail grâce au code de vérification qui vous a été envoyé par mail";
      }
   } else {
      $error = "Veuillez remplir tous les champs";
   }
}
?>


Code HTML:

<h4 class="title-element">Récupération de mot de passe</h4>
<?php if($section == 'code') { ?>
Un code de vérification vous a été envoyé par mail: <?= $_SESSION['recup_mail'] ?>
<br/>
<form method="post">
   <input type="text" placeholder="Code de vérification" name="verif_code"/><br/>
   <input type="submit" value="Valider" name="verif_submit"/>
</form>
<?php } elseif($section == "changemdp") { ?>
Nouveau mot de passe pour <?= $_SESSION['recup_mail'] ?>
<form method="post">
   <input type="password" placeholder="Nouveau mot de passe" name="change_mdp"/><br/>
   <input type="password" placeholder="Confirmation du mot de passe" name="change_mdpc"/><br/>
   <input type="submit" value="Valider" name="change_submit"/>
</form>
<?php } else { ?>
<form method="post">
   <input type="email" placeholder="Votre adresse mail" name="recup_mail"/><br/>
   <input type="submit" value="Valider" name="recup_submit"/>
</form>
<?php } ?>
<?php if(isset($error)) { echo '<span style="color:red">'.$error.'</span>'; } else { echo ""; } ?>

A propos de l'auteur

PrimFX
Boris ('PrimFX')

Je m'appelle Boris, j'ai 20 ans et je suis passionné d'informatique et de technologie. Diplômé d'une Licence Informatique de l'Université de Strasbourg, j'ai co-fondé en 2019 l'entreprise Single Quote et je profite de mon temps libre pour partager ma passion à travers des vidéos & articles sur PrimFX.com 😃

Votre commentaire

Vous devez être connecté pour poster un commentaire. Se connecter ou Créer un compte

Commentaires 34

  • LucasLuk798 Le 7 octobre, à 15:23 | Répondre

    @loulouweb Bonjour j'ai eu le même problème et Ducoup j'ai cherché et j'ai trouvé au lieu de créer un table récupération tu met la table code dans ta base de donnée membres et tu rajoute code puis sur le code tu modifie tous les champs qui comporte récupération et tu rajoute a la place le nom de la table ou il y a tes membres.
    bonne journée

  • fra91 Le 13 mai, à 17:31 | Répondre

    Un grand merci à toi jeune homme plein de talent et très prometteur, je suis un papy de 55 ans en reconversion dev web et je devais me fendre d'un petit mot pour te dire que grâce à ton travail, couplé avec openclassrooms, j'avance à grandes enjambées. J'ai fais le truc en MVC et au final tout fonctionne parfaitement! Continues car ton travail est vraiment tip-top!😉

  • oge2018 Le 14 juillet, à 10:24 | Répondre

    super tuto primfx

  • Citrus Le 9 juin, à 15:45 | Répondre

    Je tente de tester les codes après les avoir adapté à ma situation mais rien
    Les deux codes sont ils dans le même fichier ?

  • hitamjaafar Le 1 juin, à 14:34 | Répondre

    Merci

  • laraba Le 4 avril, à 17:17 | Répondre

    Merci vraiment super tuto !!!

  • aniss Le 20 mars, à 22:48 | Répondre

    Mec, pourquoi t'as pas mis tous tes fichiers (recupration mdp, mail.txt) ???? Je galère comme un chien là. Cela aurait été plus pro de tout mettre en un zip à télécharger.

  • panzer Le 23 mai, à 22:16 | Répondre

    Salut je pense avoir trouver la solution car pour moi tout fonctionne :)

    Copier-coller le lien et c'est parti: [color=#0000ff]https://www.primfx.com/forum/programmation/php/probleme-que-personne-resoudre-226#m6566[/color]

    Bonne journée ;)

  • loulouweb Le 22 avril, à 13:11 | Répondre

    Bonjour,

    Mon probleme est que rien ne rentre dans la table recuperation ! Du coup j'ai forcément le message "code invalide" quand je valide puisqu'il n'est pas présent dans la base. 
    Le code est bien généré et est bien envoyé dans la messagerie.
    QQn peut-il m'aider ? en sachant que c'est exactement le même code que l'auteur !
    Merci

  • jaewook86 Le 16 février, à 13:36 | Répondre

    Bonjour !
    C'est un super tuto mais j'aurai une question. Pourquoi l'envoi du code de récupération ne fonctionne pas sur Outlook ?
    Merci à tous ceux qui prendront le temps de me répondre..

  • bonbek Le 9 février, à 11:25 | Répondre

    TU Gèreeeeeeeeeeeeeees <3

  • zartaj12345 Le 26 janvier, à 22:07 | Répondre

    @stoppreniumm
    met tout le code dans une seule page...
    et puis ça ira!

  • blabla95 Le 19 janvier, à 20:57 | Répondre

    Bonsoir,
    SVP dans ma page, on m'ecrit comme quoi la variable $section n'est pas définie!!!Je ne sais pas comment le corriger...

    Merci de votre aide bonne journée

  • stoppreniumm Le 22 décembre, à 20:42 | Répondre

    @Zenteck Mes une connexion a ta base de donnée si sa deconne:

    <?php

    $bdd = new PDO("mysql:host=HOST;dbname=NAME DDB;charset=utf8", "NOM DDB", "MDP");

    ?>

  • stoppreniumm Le 22 décembre, à 20:38 | Répondre

    Bonjour,

    Problème sur le codage que je n'arrive pas a regler, quand je mes mon email je valide et sa me laisse sur la page ou je dois remettre l'email et valider l'email mes je recois le mail mes je reste sur la meme page.
    Peut tu m'aider ?

  • Zenteck Le 1 décembre, à 22:20 | Répondre

    bonjours, j'ai une erreur au niveau de cette ligne
    ---------------------------------
    $mailexist = $bdd->prepare('SELECT id,pseudo FROM membres WHERE mail = ?');
    --------------------------------
    le navigateur me dit:
    Undefined variable: bdd in C:\wamp\www\recuperation.php on line 17

    help please !

  • jeanboudis Le 3 novembre, à 19:29 | Répondre

    Bonjour Boris, je suis jean kevin. J'ai bien suivi le tuto et cela fonctionne bien mais quand je renseigne l'adresse mail pour signifier que je veux reinitialiser mon mot de passe, après avoir cliqué sur le bouton valider, je ne reçois rien dans mon compte mail

  • Femball Le 9 juin, à 02:16 | Répondre

    Oups
    désolé c'est ceci que j'ai rajouté dans "recuperation.php" juste apres le
    session_start();
    [Ajout]
    if(isset($_GET['section'])) {
    $section = htmlspecialchars($_GET['section']);
    } else {
    $section = "";
    }
    Et là tout fonctionne.
    Bon courage !!

  • Femball Le 8 juin, à 20:48 | Répondre

    Salut à tous.
    Pour l'erreur sur $section:
    Moi j'ai ajouté les lignes suivantes au début de mon fichier "recuperation.php" et ça fonctionne. Si ça peut aider

    if(isset($_GET['section'])) {
    $section = htmlspecialchars($_GET['section']);
    }

  • Ryma Le 7 juin, à 12:02 | Répondre

    salut svp j'ai un problème ici <?php if($section == 'code') { ?> et encore la <?php } elseif($section == "changemdp") { ?>
    quelqu’un pourrez m'aidez !!!

  • JxSDev Le 27 avril, à 13:19 | Répondre

    @kebson95
    j'ai eu la même erreur ^^ est tu arrivé à la débuguer ?

  • JxSDev Le 27 avril, à 12:29 | Répondre

    meme avec
    if(isset($_GET['section'])){
    $section = htmlspecialchars($_GET['section']);
    }
    la variable $section n'est toujours pas définies
    quelqu'un aurait une solution pour ça ??

  • wil03 Le 23 avril, à 20:29 | Répondre

    J'ai le même problème avec le Undefined index: recup_mail in et l'erreur serait à cette ligne $verif_confirme->execute(array($_SESSION['recup_mail']));
    C'est qu'il a perdu le fait qu'on soit en session?

  • Blast0Kd Le 17 avril, à 11:47 | Répondre

    @Paolacci essaye de publier ton site. En local, des erreur s'affiche alors qu'en ligne il n'y en à pas XD

  • Paolacci Le 5 avril, à 21:23 | Répondre

    Notice: Undefined index: recup_mail in
    J'arrive pas à résoudre cette erreur...

  • bigus Le 25 février, à 21:34 | Répondre

    Oups, j'ai trouvé...je n'avais pas activé MIME et SESSION sur apache !!

  • bigus Le 24 février, à 23:01 | Répondre

    @tway243
    as-tu résolu ton problème, j'ai le même et je ne trouve pas la solution ? si oui, peux tu partager !!!
    merci

  • MrDeym69 Le 17 janvier, à 16:32 | Répondre

    a la ligne 127 on a pas definie la variable $section

  • tway243 Le 5 janvier, à 03:05 | Répondre

    excelent tuto @PrimFX, cependant j'ai un petit problème avec la $_SESSION['recup_mail'] de la ligne 3 du code html ca me marque " Undefined index:"

  • kebson95 Le 25 décembre, à 20:58 | Répondre

    Fatal error: Cannot use object of type stdClass as array in C:\wamp\www...
    Salut Primfx...
    Voilà l'erreur que j'aperçois quand je teste...
    C'est au niveau de cette ligne $verif_confirme = $verif_confirme['confirme'];
    Merci d'avance

  • PrimFX Le 30 novembre, à 16:23 | Répondre

    @onesyst Merci !

  • onesyst Le 29 novembre, à 21:54 | Répondre

    Bravo PrimFX. malgres la longue durée du tuto, il est captivant et très bien expliqué.

  • PrimFX Le 29 novembre, à 15:13 | Répondre

    @TheFlameflo Ça marche, tu me diras si tout fonctionne bien ;-)

  • TheFlameflo Le 29 novembre, à 14:45 | Répondre

    J'aime bien !
    Je vais essayer de suivre le tuto, malgré qu'il soit assez long (mais vraiment utile ! ;).