Comment envoyer un email de confirmation

bonjour a tous

Avant toute chose un grand merci pour toute l'aide que j'ai reçu pour mon site
tout fonctionne impeccable et les inscriptions se suivent

Mais j'ai un soucis avec les adresses emails bidon

Je souhaiterais donc que l'utilisateur qui 'enregistre soit obliger de confirmer un email afin de pour être actif dans ma basse de donnée

Mais comment réalisé cela

Pour l'instant mon formulaire d'inscription ressemble a ceci

<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('display_startup_errors', true);
?>
<?php
// je me connecte a la base de donnee
require_once 'base.php';

//si tous est ok alors on passe a l inscription
if (!empty($_POST['pseudo']) && !empty($_POST['email']) && !empty($_POST['password']) && !empty($_POST['password_retype']))
{

    $password = ($_POST['password']);
    $password_retype = ($_POST['password_retype']);

    //preparation des variables propres
    $pseudo = !empty($_POST['pseudo']) ? $_POST['pseudo'] : NULL;
    $email = !empty($_POST['email']) ? $_POST['email'] : NULL;

    //préparation de la requête et des variables afin de vérifier si l email est présent dans la table
    $sql = "SELECT pseudo, email, password FROM utilisateurs WHERE email = ?";
    $datas = [$email];

    //Execution de la requete
    try
    {
        $requete = $bdd->prepare($sql);
        $requete->execute($datas);
    }
    catch(Exception $e)
    {

        // en cas d'erreur :
        echo " Erreur ! " . $e->getMessage();
        echo " Les datas : ";
        print_r($datas);
    }
    $data = $requete->fetch();
    $row = $requete->rowCount();
    if ($row == 0)
    {
        //préparation de la requête et des variables afin de verifier si le pseudo est present dans la table
        $sql = "SELECT pseudo, email, password FROM utilisateurs WHERE pseudo = ?";
        $datas = [$pseudo];

        //Execution de la requete
        try
        {
            $requete = $bdd->prepare($sql);
            $requete->execute($datas);
        }
        catch(Exception $e)
        {

            // en cas d'erreur :
            echo " Erreur ! " . $e->getMessage();
            echo " Les datas : ";
            print_r($datas);
        }
        $data = $requete->fetch();
        $row = $requete->rowCount();
        //on verifie que le pseudo n est pas present
        if ($row == 0)
        { //on verifie que le pseudo fais moins de 40 caractere
            if (strlen($pseudo) <= 30)
            { //on verifie que le email fais moins de 40 caractere
                if (strlen($email) <= 35)
                {
					if(preg_match('/^[a-z_\-0-9]+$/i', $pseudo))//on verifie les caracteres
					{
                    if (filter_var($email, FILTER_VALIDATE_EMAIL)) //on verifie que c est bien une email
                    
                    {
                        if ($password == $password_retype)
                        { //on verifie que le pasword retape correpond bien au passord
                            $cost = ['cost' => 12];
                            $password = password_hash($password, PASSWORD_BCRYPT, $cost);
                            $ip = $_SERVER['REMOTE_ADDR'];
                            $insert = $bdd->prepare('INSERT INTO utilisateurs(pseudo, email, password, ip, token) VALUES(:pseudo, :email, :password, :ip, :token)');
                            $insert->execute(array('pseudo' => $pseudo,'email' => $email,'password' => $password,'ip' => $ip,'token' => bin2hex(openssl_random_pseudo_bytes(24))));
							
							//traitement de l envois par mail 
							setlocale (LC_TIME, 'fr_FR.utf8','fra'); 
							date_default_timezone_set('Europe/Brussels');
							$date1 = date('d-m-Y H:i:s'); // Date du jour
							
							// on entre un ou Plusieurs destinataires
							$to  = 'perroquet666@hotmail.com'; // notez la virgule
							// Sujet
							$subject= "UN NOUVEL INSCRIT ";
							// message
							$message = 
							'
							<html>
								<head>
									<title>un nouveau membre vient de s inscrire </title>
								</head>
								<body>
									<table>
										<tr>
											<td>son pseudo est   </td><td>'.$pseudo .'</td></br>
										</tr>
										<tr>
											<td>l adresse mail    </td><td>'.$email .'</td></br>
										</tr>
										<tr>
											<td>date</td><td>'.$date1 .'</td></br>
										</tr>
									</table>
								</body>
							</html>	';
							// Pour envoyer un mail HTML, l'en-tête Content-type doit être défini
							$headers[] = 'MIME-Version: 1.0';
							$headers[] = 'content-type: text/html; charset=utf-8';
							// En-têtes additionnels
							//$headers[] =  "From: " . $name . "<". $_POST["email"] .">\r\n";
							$headers[] = 'From: '.$email."\r\n".
							'Reply-To: '.$name."\r\n" .
							'X-Mailer: PHP/' . phpversion();
							// Envoi
							//var_dump($headers);
							if(mail($to, $subject, $message, implode("\r\n", $headers))){
							// success message
							//echo "Success!<br />";
							}else{
							// error message
							//echo "Fail<br />";
							}
                               header('Location:redirection-inscription.php?reg_err=success');
                            die();
                        }
                        else
                        {
                            header('Location: inscription.php?reg_err=password');
                            die();
                        }
                    }
                    else
                    {
                        header('Location: inscription.php?reg_err=email');
                        die();
                    }
                }
				  else
                    {
                        header('Location: inscription.php?reg_err=pseudo_caractere');
                        die();
                    }
                }
                else
                {
                    header('Location: inscription.php?reg_err=email_length');
                    die();
                }
            }
            else
            {
                header('Location: inscription.php?reg_err=pseudo_length');
                die();
            }
        }
        else
        {
            header('Location: inscription.php?reg_err=already');
            die();
        }
    }
    else
    {
        header('Location: inscription.php?reg_err=already');
        die();
    }
}

9 réponses

Résumé de la discussion

La problématique centrale est d'obliger la vérification d'adresse email lors de l'inscription pour activer le compte et éviter les emails bidons. La solution recommandée consiste à ajouter un champ token et un statut (en attente/validé), générer un token unique à l'inscription et envoyer un lien de validation contenant l’id et le token. Un script de validation reçoit le token et l'id via l'URL, valide le compte en changeant le statut et, côté connexion, filtre les utilisateurs en attente. Enfin, il convient d'ajouter une vérification côté inscription et de prévoir un mécanisme de réenvoi du lien ou de réinitialisation du token en cas d'expiration, afin d'assurer l'expérience utilisateur.

Bobot (l’IA à votre service)
  1. Contributeur Ambassadeur
    bonjour,
    tu n'expliques pas comment va fonctionner la confirmation.
    1
    1. Modérateur
      Bonjour,
      Dans ta table user, il te faudra deux champs : un champ pour stocker un token ( voir ci apres) et un pour indiquer l'état du user ( en attente validation, validé .. )
      A l'inscription, tu génères un token unique que tu stockes en BDD ( dans ta table utilisateurs)
      et tu envois un lien contenant ce token à ton utilisateur ainsi que son id en bdd
      Un lien du genre
      https://tonsite.fr/validation.php?id=123&token=12464f5s654fs6f4s6df31
      


      Dans ce script validation.php, tu récupères le token qui se trouve dans le lien et l'id
      tu fais une requête qui compare avec ta bdd si les informations sont conformes .. et si oui, tu changes le statut du user en "validé"

      Bien entendu, dans ton code d'authentification des users, tu devras rajouter dans tes requêtes, un where sur l'état du user ( pour n'autoriser que ceux qui sont valides )
      1
      1. Modérateur
        On ne récupère pas les variables d'une URL via la variable $_POST...
        Mais avec la variable $_GET
        1
        1. Modérateur
          Pour le reste virgule ta requête me semble bizarre (soit tu utilises le point d'interrogation soit tu utilises une variable nommée..)
          On n'a pas déjà eu cette discussion ??
          0
      2. bonjour yg_be et jordane
        Cela faisait longtemps ...
        Merci pour les reponses
        Jordane a bien devine ce que je cherche a faire

        Alors première étape je crée deux champs par exemple token_user et etat_user
        ça c'est facile

        ensuite générer un token lors de l'inscription je suppose que cela va se passer dans ce morceau de code

        $cost = ['cost' => 12];
                                    $password = password_hash($password, PASSWORD_BCRYPT, $cost);
                                    $ip = $_SERVER['REMOTE_ADDR'];
                                    $insert = $bdd->prepare('INSERT INTO utilisateurs(pseudo, email, password, ip, token) VALUES(:pseudo, :email, :password, :ip, :token)');
                                    $insert->execute(array('pseudo' => $pseudo,'email' => $email,'password' => $password,'ip' => $ip,'token' => bin2hex(openssl_random_pseudo_bytes(24))));


        en le modifiant par

        $cost = ['cost' => 12];
                                    $password = password_hash($password, PASSWORD_BCRYPT, $cost);
                                    $ip = $_SERVER['REMOTE_ADDR'];
                                    $insert = $bdd->prepare('INSERT INTO utilisateurs(pseudo, email, password, ip, token,token_user,etat_user) VALUES(:pseudo, :email, :password, :ip, :token,token_user,etat_user)');
                                    $insert->execute(array('pseudo' => $pseudo,'email' => $email,'password' => $password,'ip' => $ip,'token' => bin2hex(openssl_random_pseudo_bytes(24),$token_user,'token_user' => bin2hex(openssl_random_pseudo_bytes(24),etat_user=>$etat_user )));


        Ensuite je dois envoyer un lien a l'utilisateur

        je suppose que je vais devoir ajouter ce code a la suite de ce que je viens de modifier

        	//traitement de l envois par mail 
        							setlocale (LC_TIME, 'fr_FR.utf8','fra'); 
        							date_default_timezone_set('Europe/Brussels');
        							$date1 = date('d-m-Y H:i:s'); // Date du jour
        							
        							// on entre l'adresse email du membre 
        							$to  = '$email'; // notez la virgule
        							// Sujet
        							$subject= "Votre lien de confirmation  ";
        							// message
        							$message = 
        							'
        							<html>
        								<head>
        									<title>voici votre lien de confirmation </title>
        								</head>
        								<body>
        									<table>
        										<tr>
        											<td>le lien est  </td><td>'.$token_user .'</td></br>
        										</tr>
        									
        									</table>
        								</body>
        							</html>	';
        							// Pour envoyer un mail HTML, l'en-tête Content-type doit être défini
        							$headers[] = 'MIME-Version: 1.0';
        							$headers[] = 'content-type: text/html; charset=utf-8';
        							// En-têtes additionnels
        							//$headers[] =  "From: " . $name . "<". $_POST["email"] .">\r\n";
        							$headers[] = 'From: '.$email."\r\n".
        							'Reply-To: '.$name."\r\n" .
        							'X-Mailer: PHP/' . phpversion();
        							// Envoi
        							//var_dump($headers);
        							if(mail($to, $subject, $message, implode("\r\n", $headers))){
        							// success message
        							//echo "Success!<br />";
        							}else{
        							// error message
        							//echo "Fail<br />";

        je suis surement pas tout a fait bon ...
        0
        1. Contributeur Ambassadeur
          tu ne fois pas envoyer le token à l'utilisateur.
          tu dois lui envoyer un lien comme celui que Jordane t'a montré en #2.
          0
        2. Modérateur
          C'est pas mal/
          Sauf le lien... en html il faut utiliser les balises <a>
          et pour la forme du lien.. regarde ce que je t'avais donné dans ma première réponse.
          1
      3. Merci de vos réponses

        Donc pour le lien que j'envois a l'utilisateur je devrais faire ceci

        <a href="https://phil.pecheperle.be/validation.php?id=$id&token_user=$token_user">Votre lien de confirmation</a>
        
        
        0
        1. Modérateur
          oui
          1
      4. Merci pour la confirmation

        une chose me tracasse c'est ce fichier validation.php

        donc je dois crée un nouveau fichier en php avec une comparaison de l'id et du token_user

        Mais la je suis un peu perdu

        je viens de trouver un code que j'ai un peu adapté
        <?php
        session_start();
        error_reporting(E_ALL);
        ini_set('display_errors', true);
        ini_set('display_startup_errors', true);
            require 'includes/db.php';
        
           //on cree une variable pour la comparer
         $tokenUser= !empty($_POST['tokenUser']) ? $_POST['tokenUser'] : NULL;
        
            $req = $bdd->prepare('SELECT id, token_user FROM membre WHERE id = ?*:id');
            if($req->execute(array(':id' => $id)) && $resultat = $req->fetch()){
                $tokenUser = $resultat['token_user'];
                $activation = $resultat['confirmed_at'];
                if($activation != NULL) {
                    echo("votre compte est déjà activé");
                } else {
                    if($tokenUsers == $token_user) {
                        echo("Votre compte est activé");
                    } else {
                        echo("Cette clé ne correspond pas");
                    }
                }
            }
             
        ?>
        0
        1. Contributeur Ambassadeur
          Il manque
          confirmed_at
          dans le SELECT.
          Et tu as négligé de récupérer la valeur de
          $id
          .
          Il manque un else et un message de retour correspondant au
          if
          en ligne 12.
          1
        2. @yg_beMerci pour la correction
          je mets le code modifié

          <?php
          session_start();
          error_reporting(E_ALL);
          ini_set('display_errors', true);
          ini_set('display_startup_errors', true);
              require 'includes/db.php';
          
             //on cree une variable pour la comparer
           $tokenUser= !empty($_POST['tokenUser']) ? $_POST['tokenUser'] : NULL;
          $id =!empty($_POST['id']) ? $_POST['id'] : NULL;
              $req = $bdd->prepare('SELECT id, token_user ,confirmed_at FROM membre WHERE id = ?*:id');
              if($req->execute(array(':id' => $id)) && $resultat = $req->fetch()){
                  $tokenUser = $resultat['token_user'];
                  $activation = $resultat['confirmed_at'];
                  if($activation != NULL) {
                      echo("votre compte est déjà activé");
                  } else {
                      if($tokenUsers == $token_user) {
                          echo("Votre compte est activé");
                      } else {
                          echo("Cette clé ne correspond pas");
                      }
                  }
              }else{
                          echo("sortie);
                      }
               
          ?>
          0
      5. oui juste jordane ...
        pour le reste tu en penses quoi ?
        0
        1. Modérateur
          C'est un bon début mais il manque la requête qui va mettre à jour le champ statut dans ta base de données
          1
        2. @jordane45Merci jordane je suppose que cela je dois le faire après
          $tokenUser = $resultat['token_user'];
                  $activation = $resultat['confirmed_at'];

          je dois mettre a jour le token_user ?mais sur ce coup la je suis dans le pétrin
          0
        3. Modérateur
          @flexi2202Requête sql update
          0
        4. @jordane45peut être comme cela
          $st = $pdo->prepare('UPDATE membre SET token_user " WHERE id = ?*:id');
          $st->execute([':token_user ' => 1]);
          0
        5. Contributeur Ambassadeur
          @flexi2202As-tu compris à quoi sert le champ
          confirmed_at
          dans la table?
          1
      6. Ah super merci pour l'aide
        je regarderais a cela demain
        Car ce jour je pars pêcher
        0
        1. voila enfin tout fonctionne grâce a ce tuto
          super bien fait
          https://www.youtube.com/watch?v=4G_EJZFmoa4

          C'était pas si évident que ça au final

          voici mes codes pour ceux que cela intéresse et peut être des corrections

          mon fichier d'inscription

          <?php
          session_start();
          error_reporting(E_ALL);
          ini_set('display_errors', true);
          ini_set('display_startup_errors', true);
          ?>
          <?php
          // je me connecte a la base de donnee
          require_once 'base.php';
          
          //si tous est ok alors on passe a l inscription
          if (!empty($_POST['pseudo']) && !empty($_POST['email']) && !empty($_POST['password']) && !empty($_POST['password_retype']))
          {
          
              $password = ($_POST['password']);
              $password_retype = ($_POST['password_retype']);
          
              //preparation des variables propres
              $pseudo = !empty($_POST['pseudo']) ? $_POST['pseudo'] : NULL;
              $email = !empty($_POST['email']) ? $_POST['email'] : NULL;
          
              //préparation de la requête et des variables afin de vérifier si l email est présent dans la table
              $sql = "SELECT pseudo, email, password FROM utilisateurs WHERE email = ?";
              $datas = [$email];
          
              //Execution de la requete
              try
              {
                  $requete = $bdd->prepare($sql);
                  $requete->execute($datas);
              }
              catch(Exception $e)
              {
          
                  // en cas d'erreur :
                  echo " Erreur ! " . $e->getMessage();
                  echo " Les datas : ";
                  print_r($datas);
              }
              $data = $requete->fetch();
              $row = $requete->rowCount();
              if ($row == 0)
              {
                  //préparation de la requête et des variables afin de verifier si le pseudo est present dans la table
                  $sql = "SELECT pseudo, email, password FROM utilisateurs WHERE pseudo = ?";
                  $datas = [$pseudo];
          
                  //Execution de la requete
                  try
                  {
                      $requete = $bdd->prepare($sql);
                      $requete->execute($datas);
                  }
                  catch(Exception $e)
                  {
          
                      // en cas d'erreur :
                      echo " Erreur ! " . $e->getMessage();
                      echo " Les datas : ";
                      print_r($datas);
                  }
                  $data = $requete->fetch();
                  $row = $requete->rowCount();
                  //on verifie que le pseudo n est pas present
                  if ($row == 0)
                  { //on verifie que le pseudo fais moins de 40 caractere
                      if (strlen($pseudo) <= 30)
                      { //on verifie que le email fais moins de 40 caractere
                          if (strlen($email) <= 35)
                          {
          					if(preg_match('/^[a-z_\-0-9]+$/i', $pseudo))//on verifie les caracteres
          					{
                              if (filter_var($email, FILTER_VALIDATE_EMAIL)) //on verifie que c est bien une email
                              
                              {
                                  if ($password == $password_retype)
                                  { //on verifie que le pasword retape correpond bien au passord
                                      $cost = ['cost' => 12];
          							$longueurkey =12;
          							$key="";
          							for($i=1;$i<$longueurkey;$i++)
          								$key .=mt_rand(0,9);
          							//$confirmkey =$key;
          							$confirme=0;
                                      $password = password_hash($password, PASSWORD_BCRYPT, $cost);
                                      $ip = $_SERVER['REMOTE_ADDR'];
                                      $insert = $bdd->prepare('INSERT INTO utilisateurs(pseudo, email, password, ip, token ,confirmkey,confirme) VALUES(:pseudo, :email, :password, :ip, :token ,:confirmkey,:confirme)');
                                      $insert->execute(array('pseudo' => $pseudo,'email' => $email,'password' => $password,'ip' => $ip,'token' => bin2hex(openssl_random_pseudo_bytes(24)),'confirmkey' => $key ,'confirme' => $confirme));
                                      
                            // on entre un  destinataires
          							$to  = $email; // notez la virgule
          							// Sujet
          							$subject= "votre confirmation";
          							// message
          							$message = 
          							'
          							<html>
          								<head>
          									<title>Votre confirmation  </title>
          								</head>
          								<body>
          									<table>
          										<tr>
          											<td>ton pseudo est   </td><td>'.$pseudo .'
          
          											
          						
          						<a href="https://phil.pecheperle.be/confirmation.php?pseudo='.urlencode($pseudo).'&key='.$key.'">Confirmez votre compte !</a>
          											
          											</td></br>
          										</tr>
          										<tr>
          											<td>l adresse mail    </td><td>'.$email .'</td></br>
          										</tr>
          										<tr>
          											<td>date</td><td>'.$date1 .'</td></br>
          										</tr>
          									</table>
          								</body>
          							</html>	';
          							// Pour envoyer un mail HTML, l'en-tête Content-type doit être défini
          							$headers[] = 'MIME-Version: 1.0';
          							$headers[] = 'content-type: text/html; charset=utf-8';
          							// En-têtes additionnels
          							//$headers[] =  "From: " . $name . "<". $_POST["email"] .">\r\n";
          							$headers[] = 'From: '.$email."\r\n".
          							'Reply-To: '.$name."\r\n" .
          							'X-Mailer: PHP/' . phpversion();
          							// Envoi
          							//var_dump($headers);
          							if(mail($to, $subject, $message, implode("\r\n", $headers))){
          							// success message
          							//echo "Success!<br />";
          							}else{
          							// error message
          							//echo "Fail<br />";
          							}
                                      
                                      
          			// on entre un ou Plusieurs destinataires
          							$to1  = 'perroquet666@hotmail.com'; // notez la virgule
          							// Sujet
          							$subject1= "UN NOUVEL INSCRIT ";
          							// message
          							$message1 = 
          							'
          							<html>
          								<head>
          									<title>un nouveau membre vient de s inscrire </title>
          								</head>
          								<body>
          									<table>
          										<tr>
          											<td>son pseudo est   </td><td>'.$pseudo .'</td></br>
          										</tr>
          										<tr>
          											<td>l adresse mail    </td><td>'.$email .'</td></br>
          										</tr>
          										<tr>
          											<td>date</td><td>'.$date1 .'</td></br>
          										</tr>
          									</table>
          								</body>
          							</html>	';
          							// Pour envoyer un mail HTML, l'en-tête Content-type doit être défini
          							$headers1[] = 'MIME-Version: 1.0';
          							$headers1[] = 'content-type: text/html; charset=utf-8';
          							// En-têtes additionnels
          							//$headers1[] =  "From: " . $name . "<". $_POST["email"] .">\r\n";
          							$headers1[] = 'From: '.$email."\r\n".
          							'Reply-To: '.$name."\r\n" .
          							'X-Mailer: PHP/' . phpversion();
          							// Envoi
          							//var_dump($headers);
          							if(mail($to1, $subject1, $message1, implode("\r\n", $headers1))){
          							// success message
          							//echo "Success!<br />";
          							}else{
          							// error message
          							//echo "Fail<br />";
          							}
          						
          							
          							
                                         header('Location:redirection-inscription.php?reg_err=success');
                                      die();
                                  }
                                  else
                                  {
                                      header('Location: inscription.php?reg_err=password');
                                      die();
                                  }
                              }
                              else
                              {
                                  header('Location: inscription.php?reg_err=email');
                                  die();
                              }
                          }
          				  else
                              {
                                  header('Location: inscription.php?reg_err=pseudo_caractere');
                                  die();
                              }
                          }
                          else
                          {
                              header('Location: inscription.php?reg_err=email_length');
                              die();
                          }
                      }
                      else
                      {
                          header('Location: inscription.php?reg_err=pseudo_length');
                          die();
                      }
                  }
                  else
                  {
                      header('Location: inscription.php?reg_err=already');
                      die();
                  }
              }
              else
              {
                  header('Location: inscription.php?reg_err=already');
                  die();
              }
          }
          


          mon fichier de validation

          	  <?php
          session_start();
          error_reporting(E_ALL);
          ini_set('display_errors', true);
          ini_set('display_startup_errors', true);
          ?>
          	  <?php
          require_once 'base.php';
           
          if(isset($_GET['pseudo'], $_GET['key']) AND !empty($_GET['pseudo']) AND !empty($_GET['key'])) {
             $pseudo = htmlspecialchars(urldecode($_GET['pseudo']));
             $key = htmlspecialchars($_GET['key']);
             $requser = $bdd->prepare("SELECT * FROM utilisateurs WHERE pseudo = ? AND confirmkey = ?");
             $requser->execute(array($pseudo, $key));
             $userexist = $requser->rowCount();
             if($userexist == 1) {
                $user = $requser->fetch();
                if($user['confirme'] == 0) {
                   $updateuser = $bdd->prepare("UPDATE utilisateurs SET confirme = 1 WHERE pseudo = ? AND confirmkey = ?");
                   $updateuser->execute(array($pseudo,$key));
                   echo "Votre compte a bien été confirmé !";
                } else {
                   echo "Votre compte a déjà été confirmé !";
                }
             } else {
                echo "L'utilisateur n'existe pas !";
             }
          }
          ?>


          ensuite il me restera la verification de la connexion
          0