Bonjour à tous,
voila mon souci, depuis peu lorsqu'un membre s'enregistre sur mon site il reçoit bien son mail de confirmation mais à chaque fois qu'il clique sur le lien cela met uniquement "Ce token n'est plus valide".
Pourtant l'enregistrement vient tout juste d'être fait et donc le délais ne devrait pas être un souci.
Tout marchait bien jusqu'à present et depuis quelques jours j'ai ce souci.
Voici mon code :
<?php require 'includes/config_index.php'; ?>
<?php
require_once 'includes/function_register.php';
if(!empty($_POST)){
$errors = array();
if(empty($_POST['nom']) || !preg_match('/^[a-zA-Z0-9_]+$/', $_POST['nom'])){
$errors['nom'] = "<font color='red'>Votre nom n'est pas valide</font>";
}
if(empty($_POST['prenom']) || !preg_match('/^[a-zA-Z0-9_]+$/', $_POST['prenom'])){
$errors['prenom'] = "<font color='red'>Votre prénom n'est pas valide</font>";
}
if(empty($_POST['age'])){
$errors['age'] = "<font color='red'>Votre date de naissance n'est pas valide</font>";
}
if(empty($_POST['club'])){
$errors['club'] = "<font color='red'>Votre club n'est pas valide</font>";
}
if(empty($_POST['categorie'])){
$errors['categorie'] = "<font color='red'>Votre catégorie n'est pas valide</font>";
}
if(empty($_POST['email']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
$errors['email'] = "<font color='red'>Votre email n'est pas valide</font>";
} else{
$req = $pdo->prepare('SELECT id FROM Membres WHERE email = ?');
$req->execute([$_POST['email']]);
$user = $req->fetch();
if($user){
$errors['email'] = '<font color="red">Cet email est déja utilisé</font>';
}
}
if(empty($_POST['tel'])){
$errors['tel'] = "<font color='red'>Votre numéro de téléphone n'est pas valide</font>";
}
if(empty($_POST['username']) || !preg_match('/^[a-zA-Z0-9_]+$/', $_POST['prenom'])){
$errors['username'] = "<font color='red'>Votre pseudo n'est pas valide</font>";
} else{
$req = $pdo->prepare('SELECT id FROM Membres WHERE username = ?');
$req->execute([$_POST['username']]);
$user = $req->fetch();
if($user){
$errors['username'] = '<font color="red">Ce pseudo est déja utilisé</font>';
}
}
if(empty($_POST['password']) || $_POST['password'] !=$_POST['password_confirm']){
$errors['password'] = "<font color='red'>Votre mot de passe n'est pas valide ou ne correspondent pas</font>";
}
if(empty($errors)){
// On enregistre les informations dans la base de données
$req = $pdo->prepare("INSERT INTO Membres SET nom = ?, prenom = ?, age = ?, club = ?, categorie = ?, email = ?, tel = ?, username = ?, password = ?, confirmation_token = ?");
// On ne sauvegardera pas le mot de passe en clair dans la base mais plutôt un hash
$password = password_hash($_POST['password'], PASSWORD_BCRYPT);
// On génère le token qui servira à la validation du compte
$token = str_random(60);
$req->execute([$_POST['nom'], $_POST['prenom'], $_POST['age'], $_POST['club'], $_POST['categorie'], $_POST['email'], $_POST['tel'], $_POST['username'], $password, $token]);
$user_id = $pdo->lastInsertId();
// On envoit l'email de confirmation
$email = ($_POST['email']);
// Adresse email du destinataire
$destinataire = $email;
// Titre de l'email
$sujet = 'Confirmation de votre compte';
// Contenu du message de l'email
$message = "Afin de valider votre compte merci de cliquer sur ce lien\n\nhttp://www.cdbf.fr/confirm.php?id=$user_id&token=$token\n\nNe répondez pas à ce mail.";
// Pour envoyer un email HTML, l'en-tête Content-type doit être défini
$headers = 'From: noreply@cdbf.fr' . "\r\n" .
$headers .='X-Mailer: PHP/' . phpversion();
// Fonction principale qui envoi l'email
mail($destinataire, $sujet, $message, $headers);
// On redirige l'utilisateur vers la page de login avec un message flash
// Adresse email du destinataire
$destinataire2 = 'cdbf.communication@cdbf.fr';
// Titre de l'email
$sujet2 = "Nouvel enregistrement";
// Contenu du message de l'email
$message2 = ($_POST['prenom'])." ". ($_POST['nom'])." s'est enregistré";
// Pour envoyer un email HTML, l'en-tête Content-type doit être défini
$headers2 = 'From: noreply@cdbf.fr' . "\r\n" .
$headers2 .='X-Mailer: PHP/' . phpversion();
// Fonction principale qui envoi l'email
mail($destinataire2, $sujet2, $message2, $headers2);
// On redirige l'utilisateur vers la page de login avec un message flash
$_SESSION['flash']['success'] = 'Un email de confirmation vous a été envoyé sur votre boîte mail.<br/> Merci de vérifier votre boîte mail pour valider votre compte.<br/> Verifiez dans vos spams si besoin.';
header('Location: login.php');
exit();
}
}
?>
<?php require 'header.php'; ?>
<body>
<?php require 'Menu.php'; ?>
<div class="row">
<div class="col-lg-offset-2 col-lg-8 col-xs-offset-1 col-xs-10">
<div class="titre">
<h3>Enregistrez-vous</h3>
</div>
<div class="col-lg-offset-0 col-lg-12 col-xs-offset-1 col-xs-10">
<?php if(!empty($errors)): ?>
<div class="alert alert-danger">
<p>Vous n'avez pas rempli le formulaire correctement </p>
<ul>
<?php foreach($errors as $error): ?>
<li><?= $error; ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<form action="" method="POST">
<div class="form-group">
<label for="">Nom</label>
<input type="text" name="nom" class="form-control" placeholder="Tapez ici votre nom" value="<?php if (isset($_POST['nom'])){echo $_POST['nom'];} ?>"/>
<?php echo $errors['nom'] ?>
</div>
<div class="form-group">
<label for="">Prénom</label>
<input type="text" name="prenom" class="form-control" placeholder="Tapez ici votre prénom" value="<?php if (isset($_POST['prenom'])){echo $_POST['prenom'];} ?>"/>
<?php echo $errors['prenom'] ?>
</div>
<div class="form-group">
<label for="">Date de naisssance</label>
<input type="date" name="age" class="form-control"/>
</div>
<div class="form-group">
<label for="">Club actuel</label>
<input type="text" name="club" class="form-control" placeholder="Tapez ici votre club" value="<?php if (isset($_POST['club'])){echo $_POST['club'];} ?>">
<?php echo $errors['club'] ?>
</div>
<div class="form-group">
<label for="">Catégorie</label><br/>
<select name="categorie" id="categorie">
<option value="">Sélectionnez votre catégorie</option>
<option value="U7">U7</option>
<option value="U9">U9</option>
<option value="U11">U11</option>
<option value="U13">U13</option>
<option value="U15">U15</option>
<option value="U17">U17</option>
<option value="U19">U19</option>
<option value="senior">Sénior</option>
</select><br/>
<?php echo $errors['categorie'] ?>
</div>
<div class="form-group">
<label for="">Email</label>
<input type="email" name="email" class="form-control" placeholder="Tapez ici votre email" value="<?php if (isset($_POST['email'])){echo $_POST['email'];} ?>"/>
<?php echo $errors['email'] ?>
</div>
<div class="form-group">
<label for="">Téléphone</label>
<input type="text" name="tel" class="form-control" placeholder="Tapez ici votre numéro de téléphone" value="<?php if (isset($_POST['tel'])){echo $_POST['tel'];} ?>"/>
<?php echo $errors['tel'] ?>
</div>
<div class="form-group">
<label for="">Pseudo</label>
<input type="text" name="username" class="form-control" placeholder="Tapez ici votre pseudo" value="<?php if (isset($_POST['username'])){echo $_POST['username'];} ?>"/>
<?php echo $errors['username'] ?>
</div>
<div class="form-group">
<label for="">Mot de passe</label>
<input type="password" name="password" class="form-control" placeholder="Tapez ici votre mot de passe" value="<?php if (isset($_POST['password'])){echo $_POST['password'];} ?>"/>
<?php echo $errors['password'] ?>
</div>
<div class="form-group">
<label for="">Confirmez votre mot de passe</label>
<input type="password" name="password_confirm" class="form-control" placeholder="Tapez ici votre mot de passe" value="<?php if (isset($_POST['password_confirm'])){echo $_POST['password_confirm'];} ?>"/>
<?php echo $errors['password'] ?>
</div>
<button type="submit" class="btn btn-primary">M'inscrire</button>
</form>
</div>
</div>
</div>
<?php require 'Footer.php'; ?>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>
J'ai beau chercher et je ne trouve pas ou ça bloque.
Quelqu'un aurait une idée ?
Merci d'avance.
Bonsoir.
Ton sujet concerne la confirmation d'un compte avec un token, mais tu ne nous montre que le code pour enregistrer le compte, mais pas celui qui concerne justement la confirmation.
Donc, à moins de faire des suppositions, il nous est impossible de voir d'où peut venir le problème et pour information, nous n'avons pas envie de perdre du temps pour t'aider en faisant des suppositions.
le code de confirmation est exactement le même que celui proposer par grafikart, c'est pour cela que je ne l'ai pas poster.
Pensant que l'erreur ne pouvait pas venir de lui.
Le voici :
<?php
$user_id = $_GET['id'];
$token = $_GET['token'];
require 'includes/db.php';
$req = $pdo->prepare('SELECT * FROM Membres WHERE id = ?');
$req->execute([$user_id]);
$user = $req->fetch();
session_start();
if($user && $user->confirmation_token == $token ){
$pdo->prepare('UPDATE Membres SET confirmation_token = NULL, confirmed_at = NOW() WHERE id = ?')->execute([$user_id]);
$_SESSION['flash']['success'] = 'Votre compte a bien été validé';
$_SESSION['auth'] = $user;
header('Location: accueil.php');
}else{
$_SESSION['flash']['danger'] = "Ce token n'est plus valide";
header('Location: login.php');
}
En espérant que cela puisse vous aider.
Merci d'avance.
Salut,
moi ce qui m'embête un peu c'est de devoir lire un code mal balisé, et mal indenté...
(en plus il y a beaucoup trop d'infos par rapport à ce qui est utile. Et en plus il manquait de l'info utile) ^^
Enfin bref...
Avant ça fonctionnait tu dis ?
Tu as touché au code entre temps ?
...
$token = $_GET['token'];
...
il y a quoi dans le href
du lien sur lequel on clic pour activer le compte ? (dans l'email de l'utilisateur)
Et mets quelques 'debug' pour voir (au moins sur $token
et $user
) :
$token = $_GET['token'];
echo 'TOKEN : ' . $token . '<br>';
require 'includes/db.php';
$req = $pdo->prepare('SELECT * FROM Membres WHERE id = ?');
$req->execute([$user_id]);
$user = $req->fetch();
echo '*** USER ***<br>';
echo '<pre>';
echo print_r($user);
echo '</pre>';
Rien à voir mais,
c'est Grafikart qui a écrit ça ??
$user->confirmation_token
Pas bieeeeen.... ^^
MErci,
haha oui c'est bien lui.
Je pense avoir trouver ou était le problème.
Voila un bout du token qui s'ajoute à ma base mysql :
M7xiTLeB4qGDKHmJ75dm6LFrmuCbc8ne?oZasMlLTV44bsZUnV
et voici le token que je reçois sur mon mail :
M7xiTLeB4qGDKHmJ75dm6LFrmuCbc8ne�oZasMlLTV44bsZUnVGVK�S2T1xo
Enfaite depuis peu je ne sais pas pourquoi dans mon token il y"a des "?".
Cela entraine des symboles non reconnus sur mon mail.
Comment puis-je faire ?
Enlever les "?" dans le token ?
Mais je ne vois pas comment faire.
ou bien rendre lisible ces symboles dans le mail ?
Je ne sais pas non plus comment le faire.
Une idée ?
Ah zut,
est-ce que tu utilises PHPMailer pour envoyer les emails ?
Si oui,
tu peux définir l'encodage des caractères de cette façon :
$mail = new PHPMailer;
$mail->CharSet = "utf-8";
J'imagine que ça devrait résoudre le problème.
Si tu n'utilises pas PHPMailer,
je ne sais pas comment faire.
Mais comme ton token est initialisé de cette façon :
$token = str_random(60);
Tu peux peut-être modifier la façon de générer un token,
ou alors,
tu le génères de la même façon, mais ensuite tu fais un str_replace
sur les '?' (seulement s'il n'y a que les points d'interrogations qui posent problème...)
Mais ça parait bien foireux comme "solution", si un moment tu tombes sur un nouveau caractère qui sera pas géré ça va rebuguer... Pas terrible...
Merci,
pour ma part j'utilise ceci :
$headers = 'From: noreply@cdbf.fr' . "\r\n" .
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=UTF-8\r\n";
$headers .='X-Mailer: PHP/' . phpversion();
Même avec ça, ça ne veut pas.
Je ne comprends donc pas pourquoi.
De plus avant je n'avais jamais de "?" dans mon token.
Je ne comprends pas pourquoi maintenant il y 'en a maintenant.
Une idée d'ou cela peut il venir ?
Ah ben zut alors, tu avais déjà l'utf-8. Mince.
De plus avant je n'avais jamais de "?" dans mon token.
Une idée d'ou cela peut il venir ?
Pas du tout... :'(
Je vais chercher.
Je pense que le souci ne vient que de la car quand je fais un copier coller du lien et que je corrige le symbole il me met bien " votre compte a bien été valider".
En tout cas merci pour vos pistes.
Si jamais quelqu'un d'autre a des idées, je suis preneur =)
Bonjour.
Ton problème ne vient pas juste de l'encodage, mais aussi de la taille de ton champ en base de données.
Car comme on peut le voir, en base de données, c'est une chaîne de 50 caractères qui est sauvegardée, alors que tu génères une chaîne de 60 caractères.
Ce qui fait que la comparaison sera toujours fausse entre la valeur récupérée dans l'url et celle que tu récupères de la base de données.
Merci Lartak,
cependant pourquoi avant ça marchait bien ?
Et pourquoi grafikart a choisit 60 alors ?
Je ne pense pas, il n'a mis qu'un bout du token
Voila un bout du token qui s'ajoute à ma base mysql :
Et quand il remplace à la main les pts d'interrogations, ça fonctionne bien
quand je fais un copier coller du lien et que je corrige le symbole il me met bien " votre compte a bien été valider".
Je ne pense pas, il n'a mis qu'un bout du token
S'il ne nous donne pas le code correct, mais seulement des bouts, il ne faut pas qu'il s'attende à ce que nous puissions l'aider correctement.
Pour ce qui concerne l'encodage, il faut souvent faire attention aux encodages :
Si l'encodage est incorrect au niveau de l'éditeur/IDE, la fonction mail ne pourra pas corriger la chaîne de caractères qui lui est soumise.
Je suis d'accord avec toi Lartak pour l'encodage mais je n'ai rien changer dessus et avant ça marchait niquel.
Tout cela pendant un an et la d'un coup ça ajoute des "?".
Je ne sais donc pas pourquoi.
J'ai mis qu'un bout car sur les 60 caractères j'en avais que 50 d'afficher sur ma base de donné sinon il fallait cliquer sur l'ID pour tout afficher mais j'y ai pas penser sur le coup.
Salut,
Tu n'as pas mis à jour PHP, la fonction str_random ressemble exactement à celle de @Grafikart, à quoi ressemble ton token avant insertion, dans ta base et après récupération?
Salut Thomas,
quel version PHP faut-il ?
Avant insertion ?
Tu veux dire celui qui est insérer ?
car après ça devient un Null et ça va dans Confirm_at.
Sinon le premier token c'est :
2m7hfA16enMoxgifCPjn?V9YZdUJ7RZXzPrV7uzx
et celui dans le mail :
http://www.cdbf.fr/confirm.php?id=309&token=2m7hfA16enMoxgifCPjn%EF%BF%BDV9YZdUJ7RZXzPrV7uzx
Ce qui fait qu'ils ne se correspondent pas.
MAis je ne vois pas d'ou vient le souci car avant tout fonctionnait parfaitement.
Je veux juste savoir si entre temps tu aurais changé de version de PHP et plus particulièrement d'encodage. Après, je pense que ton problème vient d'avant d'insérer le token en base car si tu utilises la même version du str_random, tu ne devrais pas avoir de ?. Essaie
utf8_decode($token)
au moment de l'insertion du token en base.
Pourquoi obtiens-tu les fameux caractères '?' (point d'interrogation sur fond noir = REPLACEMENT CHARACTER = code unicode EF BF BD) c'est ce qu'on retrouve dans ton url.
Si tu a eu ces caractères c'est que tu as mélangé des caractères multibyte et qu'en les mélangeant tu as formé des caractères qui n'existent pas.
Dans la vidéo de Graphikart, il utilise une chaine $alphabet = "123456789azertyuiopqsdfghjklmwxcvbnAZERT ...."
il n'utilise pas de caractères accentués (multibyte)
comme php ne gère pas l'utf-8 (sauf les fonction mb_*) il ne sait pas qu'un 'é' représente un caractère, il en voit 2
revoit la fonction qui génère le token (vidéo "Gestion d'un espace membre en php"
vers 34')