Bonjour, je suis étudiante en première année de BUT MMI.
Dans le cadre de la validation de mes compétences de ma formation, un projet, en groupe, nous a été confier dans lequel nous devions créer une espace ou la connexion et l'inscription doivent y être présente. Tout les langages sont, bien sure, de mises avec en prime SQL à relier avec le PHP.
J'ai écrit une requête dans laquelle, au moment de la connexion, ma requête SQL reprend ce que l'utilisateur a inscrit dans les champs et les compare avec ce qu'il a enregistrer dans la base de donnée. Si il trouve un résultat, il le stockera dans une variable, soit le nombre 1 pour 1 résultat, et lui ouvrira une session. Dans le cas contraire, il le redirigera vers la page et lui affichera que le mot de passe est incorrect.
Le problème est que depuis un moment, maintenant, après mon changement de serveur, un problème avec la page de connexion est apparu. Il me redirigeais en continue vers la page de connexion ou il affichait que le mot de passe était incorrect. J'ai découvert que le problème venait du fait que chaque fois que la requête SQL s'éxécutait, il ne trouvait aucun résultat. Je me suis donc, directement, tournée vers la requête SQL. J'ai trouvé qu'une partie de la requête était considérér comme une chaine de charactère entre guillement et non une part de la requête.
$sql= 'SELECT COUNT(*) FROM personne WHERE mot_de_passe = "'.$mot.'" AND email = "'.$email.'"';
Ce que je veux
Je souhaiterais qu'il considère "AND email" dans la requête.
Ce que j'obtiens
J'ai mis, presque, dans tout les sens, les guillemets. J'ai tout tenter mais je ne trouve pas le problème. S'il-vous-plait, HELP ME!!
Oh que si il y a des soucis avec et password_hash génère des hash random car il ajoute une chaine random que l'on nomme "sel" qui est chiffré dans le hash.
Du coup déjà choisi entre mysqli ou pdo mais pas les 2. Perso je préfère PDO mais c'est un choix perso.
Ensuite du coup tu as une possibilité d'injection sql dans la requête et donc la si tu mets en ligne ce code on peut soit se connecter sans le mot de passe voir pire, récupérer et / ou détruire toute ta base de donnée.
Je reviens avec un code pour l'inscription et la connexion mais le mieux serait que je te montre directement sur discord car sinon ça va faire un échange interminable si tu n'arrive pas à visualiser tes erreurs. Je suis co en ce moment sur grafikart (pseudo quenti77 comme ici)
Et vous ne savez pas du tout ou est le problème dans mon code? (Je suis désolée, j'ai eu beaucoup de mal à arriver jusqu'à ce code en php et comme je sais qu"il a changer brusquement à la suite du changement de serveur, je me dit que le problème doit être petit et que j'aimerai autant éviter y toucher. Ca ne veut, en aucun cas, dire que je crache sur le code que vous m'avez envoyez. Loin de là et d'ailleurs mille merci à vous de m'avoir répondu. Mais, j'aimerais, juste si possible, d'essayer directement de localiser le problème dessus. Je suis sincèrement désole si je vous ai offansée.
Bonjour, essaie ça :
$sql= "SELECT COUNT(*) FROM personne WHERE mot_de_passe = '$mot' AND email = '$email'";
Bonjour,
Ton probleme c'est qu'il ne trouve pas la personne dans la base de donnee, ce n'est pas un probleme de la requette sql, a mon avis.
Pourtant, j'ai vérifier un nombre inculable de fois si tout était bien écrit dans la base de donnée. Surtout qu'au cours de la création de compte, l'email et le mot de passe était similaire.
Je vais quand même vous prendre une photo de la base de donnée..Ou, en tout cas, je vais essayer
Si tu elèves la condition, qu'est-ce-que tu obtiens?
$sql= "SELECT COUNT(*) FROM personne "
Bonjour,
Est-ce que tu as hachée ton mot de passe en base de données ? Si c'est le cas, tu dois aussi le hacher quand tu fais ta comparaison dans ta requête SQL.
Sinon pour éviter de faire des concaténations de chaînes de caractères, utilise la fonction bindParam de PHP disponible avec PDO.
Lien vers la documentation : https://www.php.net/manual/fr/pdostatement.bindparam.php
Pour Monsieur BOUTIN, il entre dans la troisième condition :
"""
if ($data[0] == 1) {
session_start();
$_SESSION['email'] = $_POST['email'];
header('Location:membre.php');
data_unset();
exit();
}
elseif ($data[0] == 0) {
echo"<div class='box'>";
echo"<img id='gif' src='non.gif' alt='GIF d'une fille disant non'><br/>";
echo"</div>";
echo"<div id='box2'>";
$erreur = 'Login ou mot de passe non reconnu !';
echo "<br/>".$erreur."<br/>";
echo"<a href='accueil.php'>Accueil</a>";
echo"</div>";
exit();
}
else {
$erreur = 'Erreur de saisie !</br> Au moins un des champs est vide !'; echo $erreur;
echo "<br/><a href='accueil.php'>Accueil</a>";
exit();
}
"""
"Erreur de saisie !
Au moins un des champs est vide !"
Pour Nathe, j'ai hasher les mots de passe. Et la ligne qui le permettait a été stocker dans une variable avec le mot de passe entrer par l'utilisateur. Je vous met la ligne :
"""
$mot = hash("sha256", $_POST["mdp"]);
$email = $_POST['email'];
$sql= "SELECT COUNT(*) FROM personne WHERE mot_de_passe= '$mot' AND email='$email'";
"""
En tout cas, je vais tenter avec BindParam. Dès que j'ai fini, je reviens vers vous :)
Hello,
Je ne sais pas si c'est un vieux projet mais de nos jours, les mdp des utilisateurs ne sont plus hash avec du sha256.
En php il y a 2 fonctions à connaitre pour les mdp qui sont password_hash
et password_verify
// Inscription
$nickname = $_POST['nickname'] ?? null;
$email = $_POST['email'] ?? null;
$password = $_POST['password'] ?? null;
// Les vérifications des champs et autre ...
// Si tout est ok, on enregistre l'utilisateur
$reqInsert = $pdo->prepare('INSERT INTO users (nickname, email, password) VALUES (:nickname, :email, :password)');
$reqInsert->execute([
'nickname' => $nickname,
'email' => $email,
'password' => password_hash($password, PASSWORD_DEFAULT, ['cost' => 14]),
]);
Le champs password en base de données doit être un varchar(255) sinon tu pourrai avoir le hash qui est coupé.
// Connexion
$email = $_POST['email'] ?? null;
$password = $_POST['password'] ?? null;
// Les vérifications des champs et autre ...
// Si tout est ok, on vérifie que l'utilisateur existe
$reqUser = $pdo->prepare('SELECT id, nickname, email, password FROM users WHERE email = :email');
$reqUser->execute(['email' => $email]);
$user = $reqUser->fetch();
// Si l'utilisateur existe, on vérifie le mot de passe
if ($user === false || !password_verify($password, $user->password)) {
// Si le mot de passe est incorrect, on affiche un message d'erreur
$_SESSION['flash']['danger'] = 'Identifiants incorrects';
header('Location: login.php');
exit();
}
// Si le mot de passe est correct, on connecte l'utilisateur
$_SESSION['user'] = $user;
header('Location: index.php');
exit();
Version de base mais l'idée est là.
Alors, j'ai écris avec "bind_params" :
$sql= "SELECT COUNT(*) FROM personne WHERE mot_de_passe= :mot AND email=:email";
$mot = hash("sha256", $_POST["mdp"]);
$email = $_POST['email'];
$ql->bindParam(':mot', $mot);
$ql->bindParam(':email', $email);
$req = mysqli_query($connexion, $sql) or die ('Erreur SQL == '.$sql.'</br>'.mysqli_error($connexion));
$data = mysqli_fetch_array($req);
mysqli_free_result($req); mysqli_close($connexion);
Le problème, c'est que 3 messages d'erreurs sont affichée à cause du bind_param :
Je te conseil de faire plus attention à ce que tu code. Regarde bien la variable après $email
tu as mis $ql
au lieu de $sql
et de toute façons c'est complètement faux.
Je t'invite vivement à refaire une formation php : https://grafikart.fr/formations/php
Alors, j'ai tout modifiée mais la pour le coup, j'ai eu une erreur qui persiste.
=> TypeError: mysqli_query(): Argument #2 ($query) must be of type string
voici le code :
<?php
try{
$db = new PDO(
'mysql:host=127.0.0.1;dbname=reservation_site;charset=utf8',
'root'
);
$db -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(Exception $e){
die(print_r($e));
}
if (!empty($_POST['email']) && !empty($_POST['mdp'])) {
$mot = hash("sha256", $_POST["mdp"]);
$email = $_POST['email'];
$connexion = mysqli_connect('127.0.0.1', 'root', '', 'reservation_site');
$sql = $db->prepare('SELECT COUNT(*) FROM personne WHERE email = "'.$email.'" AND mot_de_passe= "'.$mot.'"');
$req = mysqli_query($connexion, $sql) or die ('Erreur SQL == '.$sql.'</br>'.mysqli_error($connexion));
$data = mysqli_fetch_array($req);
mysqli_free_result($req);
if ($data[0] == 1) {
session_start();
$_SESSION['email'] = $_POST['email'];
header('Location:membre.php');
data_unset();
exit();
}
elseif ($data[0] == 0) {
echo"<div class='box'>";
echo"<img id='gif' src='non.gif' alt='GIF d'une fille disant non'><br/>";
echo"</div>";
echo"<div id='box2'>";
$erreur = 'Login ou mot de passe non reconnu !';
echo "<br/>".$erreur."<br/>";
echo"<a href='accueil.php'>Accueil</a>";
echo"</div>";
exit();
}
else {
$erreur = 'Erreur de saisie !</br> Au moins un des champs est vide !'; echo $erreur;
echo "<br/><a href='accueil.php'>Accueil</a>";
exit();
}
}
?>
Pour quenti77,
le "14" et "cost" représente quoi dans la ligne que vous avez écrite.
'password' => password_hash($password, PASSWORD_DEFAULT, ['cost' => 14]),
Ensuite, j'ignorais totalement que Grafikart proposait une formation. C'est génial. Je m'y pencherai dès que j'aurais fini ce code. C'est promis ✋
Le cost est une valeur de cout de génération. En fonction de ce cost le temps de génération est plus ou moins long. Il ne faut pas qu'il soit trop élever car sinon ça prends du temps. 14 est une bonne valeur.
j'ai essaye ce code chez moi et ca marche bien:
**<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="" method="post">
<input type="email" name="email">
<input type="password" name="mdp">
<input type="submit" value="Connecter">
</form>
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
/*$requete = "INSERT INTO personne (email, mot_de_passe ) VALUES ( ? , ?)";
//on prépare la requête
$reqPrep = mysqli_prepare($connexion, $requete);
//si la requête préparée fonctionne
if ($reqPrep) {
//Crypter le mot de passe
//$password = password_hash($password, PASSWORD_DEFAULT);
$password = hash("sha256", "test");
$email = "test@test.com";
//faire le lien
mysqli_stmt_bind_param($reqPrep, "ss", $email, $password);
//exécute la requête
mysqli_stmt_execute($reqPrep);
// return erreur si ya erreur et true si pas d'erreur
$erreur = mysqli_stmt_error($reqPrep);
return $erreur != "" ? $erreur : false;
}
die;
*/
//print_r($_POST);
if (!empty($_POST['email']) && !empty($_POST['mdp'])) {
$connexion = mysqli_connect('127.0.0.1', 'test', 'test', 'test');
if (!$connexion) {
echo "LA CONNECTION AU SERVEUR A ECHOUE";
exit;
}
// mysqli_select_db($connexion, BDD);
$mot = hash("sha256", $_POST["mdp"]);
$email = $_POST['email'];
$sql = 'SELECT COUNT(*) FROM personne WHERE mot_de_passe = "' . $mot . '" AND email = "' . $email . '"';
$req = mysqli_query($connexion, $sql) or die('Erreur SQL == ' . $sql . '</br>' . mysqli_error($connexion));
$data = mysqli_fetch_array($req);
mysqli_free_result($req);
mysqli_close($connexion);
if ($data[0] == 1) {
session_start();
$_SESSION['email'] = $_POST['email'];
header('Location:membre.php');
//data_unset();
exit();
} elseif ($data[0] == 0) {
$erreur = 'Login ou mot de passe non reconnu !';
echo $erreur;
echo "<br/><a href='accueil.php'>Accueil</a>";
exit();
} else {
$erreur = 'Erreur de saisie !</br> Au moins un des champs est vide !';
echo $erreur;
echo "<br/><a href='accueil.php'>Accueil</a>";
exit();
}
}
?>
</body>
</html>**
Eviter de mettre des codes en entier et surtout mal formatté. Il faut que l'auteur apprene comment faire.
Alors, pour le hashage du mot de passe, je l'ai modifier. Maintenant, le problème avec mysqli_query() se pose toujours😅
Alors, à l'heure actuel, il ressemble à ça mon code :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href='reservation.css' rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk&display=swap" rel="stylesheet">
<title>Vérification</title>
</head>
<body>
<?php
try{
$db=new PDO(
'mysql:host=127.0.0.1;dbname=reservation_site;charset=utf8',
'root'
);
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}
catch(Exception $e){
die(print_r($e));
}
if (!empty($_POST['email']) && !empty($_POST['mdp'])) {
$mot = password_hash($_POST['mdp'], PASSWORD_DEFAULT, ['cost' => 14]);
$email = $_POST['email'];
$connexion = mysqli_connect('127.0.0.1','root','','reservation_site');
$sql = 'SELECT COUNT(*) FROM personne WHERE email = :email AND mot_de_passe= :mot_de_passe';
$insertScore = $db->prepare($sql);
$sqlParams = [
'email' => $_POST["email"],
'mot_de_passe' => password_hash($_POST['mdp'], PASSWORD_DEFAULT, ['cost' => 14]),
]
$insertScore->execute($sqlParams) or die($db->errorInfo());
$data = mysqli_fetch_array($sql);
mysqli_free_result($sql);
if ($data[0] == 1) {
session_start();
$_SESSION['email'] = $_POST['email'];
header('Location:membre.php');
data_unset();
exit();
}
elseif ($data[0] == 0) {
echo"<div class='box'>";
echo"<img id='gif' src='non.gif' alt='GIF d'une fille disant non'><br/>";
echo"</div>";
echo"<div id='box2'>";
$erreur = 'Login ou mot de passe non reconnu !';
echo "<br/>".$erreur."<br/>";
echo"<a href='accueil.php'>Accueil</a>";
echo"</div>";
exit();
}
else {
$erreur = 'Erreur de saisie !</br> Au moins un des champs est vide !'; echo $erreur;
echo "<br/><a href='accueil.php'>Accueil</a>";
exit();
}
}
?>
</body>
</html>
Mais le nouveau message d'erreur c'est celui-ci :
Parse error: syntax error, unexpected variable "$insertScore"
Hello,
Quand tu as des erreurs, pense à utiliser la fonction var_dump() de php, elle est plutôt utile !
Aussi, regarde bien à quelle ligne il te mets l'erreur.
Ici il te manque tout simplement un ; à la fin de
$sqlParams = [
'email' => $_POST["email"],
'mot_de_passe' => password_hash($_POST['mdp'], PASSWORD_DEFAULT, ['cost' => 14]),
]
:)
Il semble que le problème soit lié à l'utilisation des guillemets dans votre requête SQL. En effet, les guillemets que vous utilisez pour entourer les variables $mot et $email sont considérés comme des chaînes de caractères et ne sont pas interprétés comme faisant partie de la requête SQL.
Pour résoudre ce problème, vous pouvez utiliser des guillemets inversés (`) pour entourer les noms des colonnes dans la requête, et des guillemets simples pour entourer les valeurs de chaînes de caractères. Par exemple :
$sql= "SELECT COUNT(*) FROM personne WHERE mot_de_passe = ? AND email = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$mot, $email]);
$count = $stmt->fetchColumn();
Notez que dans cet exemple, $pdo est un objet PDO qui représente une connexion à la base de données. Vous devez remplacer ce code avec votre propre code qui crée la connexion à votre base de données.
Pour Nathe, de ce que j'ai vue, var_dump me renvoie la type de ma requête. Il la considère comme une chaine de caractère. Et mysqli_query() n'en veut pas.
Pour Monsieur CHAUSSAROUX,
Alors, pour les guillemets inversées, je n'ai pas très bien compris.
Est ce que voulez dire que les guillements inversées et normales doivent être écrites de cette façon ?
$sql= "SELECT COUNT(*) FROM personne WHERE mot_de_passe
='$mot' AND email
= '$email'";
Alors, actuellement, mon code ressemble à ça :
if (!empty($_POST['email']) && !empty($_POST['mdp'])) {
$connexion = mysqli_connect('127.0.0.1','root','','reservation_site');
$mot = password_hash($_POST['mdp'], PASSWORD_DEFAULT, ['cost' => 14]);
$email = $_POST['email'];
$sql = "SELECT COUNT(*) FROM personne WHERE `email` ='$email' AND `mot_de_passe`= '$mot'";
$insertScore = $db->prepare($sql);
var_dump($sql);
$insertScore->execute([
'email' => $email,
'mot_de_passe' => $mot,
]) or die($db->errorInfo());
$data = $insertScore->fetchColumn();
mysqli_free_result($sql);
Maintenant, un autre problème se pose. Je vous l'affiche :
C:\wamp64\www\reservation_site\connexion.php:35:string 'SELECT COUNT(*) FROM personne WHERE email
='boubousept2@gmail.com' AND mot_de_passe
= '$2y$14$xJsFymd05H2ft5j.JH/AWujVG8XlmsScFIJ74ejs2FifMFqaK14Wi'' (length=152)
( ! ) Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in C:\wamp64\www\reservation_site\connexion.php on line 38
( ! ) PDOException: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in C:\wamp64\www\reservation_site\connexion.php on line 38
Re,
dans ta requête SQL, essaye de mettre des : devant tes paramètres. Ce qui donnerait
$sql = "SELECT COUNT(*) FROM personne WHERE email = :email AND mot_de_passe= :mot_de_passe;
Alors, j'ai tentée et voila, ce qu'il m'affiche :
C:\wamp64\www\reservation_site\connexion.php:35:string 'SELECT COUNT(*) FROM personne WHERE email
=':email' AND mot_de_passe
= ':mot_de_passe'' (length=90)
( ! ) Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in C:\wamp64\www\reservation_site\connexion.php on line 38
( ! ) PDOException: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in C:\wamp64\www\reservation_site\connexion.php on line 38
Je n'ai pas l'impression qu'il reconnaisse "email" et "mot_de_passe" quand je lui met les deux points devant. Comparé à tout à l'heure ou il faisait directement le lien et affichait les valeurs correspondantes. 🤔
Je pense vraiment qu'il faut reprendre les cours et lire les erreurs qui sont (peut être par habitude) explicite.
Si tu es sur le discord de Garfikart, je pense que tu peux me trouver, ça serait pas mal de voir ensemble ce que tu as fait.
Je pense que c'est une bonne idée de passer sur discord, ça sera plus simple.
Le soucis ici je pense surtout c'est que tu as laissé les guillemets autour de :email et :mot_de_passe.
Si tu veux des exemples de comment ça s'utilise : https://www.php.net/manual/fr/pdostatement.bindparam.php
Mais il s'avère que le hash de mon mot de passe dans la base de donnée et après la supressions de mon compte et le changement de hashage, chaque fois qu'il le compare, il a raison. La raison est simple :
Les hashs sont différents :
=> Celui de la base de donnée :
$2y$14$Psjf82vcdfomb/7TIQBZG.2HVgDECW/k04ueIFcQ5yK
=> Celui obtenue avec le code :
$2y$14$F9t6fCPVAcvYAiZgnYOQ9OZ2omH.Amo6tYW.hklKVgveZzyP84AtK
Cela veut dire que tu n'a pas mis assez de characètre sur le type de la colonne pour enregistrer ton mot de passe.
J'aimerai quand même voir ton code un de ces 4, car je ne suis pas sur qu'il soit ok.
oki doki. Le voici :
try{
$db=new PDO(
'mysql:host=127.0.0.1;dbname=reservation_site;charset=utf8',
'root'
);
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}
catch(Exception $e){
die(print_r($e));
}
if (!empty($_POST['email']) && !empty($_POST['mdp'])) {
$connexion = mysqli_connect('127.0.0.1','root','','reservation_site');
$email = $_POST['email'];
$mot = hash("sha256", $_POST["mdp"]);
$sql = "SELECT COUNT(*) FROM personne WHERE email = '$email' AND mot_de_passe = '$mot' ";
$insertScore = mysqli_query($connexion,$sql) or die ('Erreur SQL == '.$sql.'</br>'.mysqli_error($connexion));
$data = mysqli_fetch_array($insertScore);
var_dump($sql);
var_dump($data);
mysqli_free_result($insertScore);
Il s'est avérée que le problème ne venait, non pas, de la longueur du mot de passe établi dans la base de donné mais dans le hashage lui-même. J'ai remis le SHA256 et il a, soudainement, refonctionner :). J'ignore pourquoi mais le hash était différent de celui de l'inscription. Très bizarre :) Mais la consigne étant qu'on évite SHA 1 et MD5, il ne devrait pas avoir de problème avec SHA256
AIE AIE AIE...A l'heure actuelle, je ne peux pas..Et demain, je suis pendant deux 3 heures dans les bagages avec ma famille et dans la voiture sur 3 heures aussi. Dès que je rentre chez moi, je vous envoie un message sur Discord (Normalement, ce sera demain en fin d'après midi, début de soirée ou samedi).
Je suis désolé, sincèrement. Je ne peux pas faire mieux.
Quoi qu'il en soit, merci pour votre aide Nathe, Monsieur CHOUSSAROUX, Monsieur BOUTIN, Monsieur Allad et, bien sure, vous quenti77 :)