[RESOLU] soucis avec password_verify

Eléphanteau du PHP | 23 Messages

23 avr. 2015, 11:57

Bonjour à tous,

Après avoir fait de multiple recherche et chercher par moi-même la solution, je n'ai pas trouvé !!!
Je hashe les mots de passe avec password_hash et je les vérifie avec password_verify. Manuellement cela fonction mais quand je doit récupérer le mot de passe via la base de données, le mot de passe ne correspond pas ou il ne le trouve pas...

Voici le formulaire :
<?php
include('connexion.php');
include('creation.php');
?>
<html>
<head>
<title>Accueil</title>
</head>

<body>
Creer un mot de passe :<br />
<form action="index.php" method="post">
<!-- Login : <input type="text" name="login" ><br /> -->
Mot de passe : <input type="password" name="pass"><br />
<input type="submit" name="creer" value="creer">
</form>

Connexion à l'espace membre :<br />
<form action="index.php" method="post">
<!-- Login : <input type="text" name="login" ><br /> -->
Mot de passe : <input type="password" name="pass"><br />
<input type="submit" name="connexion" value="Connexion">
</form>
<a href="inscription.php">Vous inscrire</a>
</body>
</html>
la page creation:
<?php 
if (isset($_POST['creer']))
{
	if (empty($_POST['pass']))
	{
		echo 'Le mot de passe est vide.';
	}
	else
	{
		$passe_admin = htmlspecialchars(trim($_POST['pass']));
		$hash = password_hash($passe_admin, PASSWORD_BCRYPT, ['cost' => 12]);
		
		$connexion_base_de_donnees = new PDO('connexion a la base de données');
		$connexion_base_de_donnees->exec('SET NAMES utf8');
		
		if (!$connexion_base_de_donnees)
		{
			echo '<font color="red">La connexion au serveur rencontre des difficultées.</font>';
			
		}
		else
		{
			$connexion_accepter = $connexion_base_de_donnees->prepare("INSERT INTO admin (mdp) VALUES (:pass)");
			$connexion_accepter->bindParam(':pass', $hash);
			
			$connexion_accepter->execute();
		}
	}
}
$connexion_base_de_donnees = null;
et la page connexion:
<?php
if (isset($_POST['connexion']))
{
	if (empty($_POST['pass']))
	{
		echo 'Le mot de passe est vide.';
	}
	else
	{
		$passe_admin = htmlspecialchars(trim($_POST['pass']));
		$connexion_base_de_donnees = new PDO('connexion a la base de données');
		$connexion_base_de_donnees->exec('SET NAMES utf8');
		
		if (!$connexion_base_de_donnees)
		{
			echo '<font color="red">La connexion au serveur rencontre des difficultées.</font>';
			
		}
		else
		{
			$connexion_accepter = $connexion_base_de_donnees->prepare("SELECT * FROM admin WHERE mdp = :pass");
			$connexion_accepter->bindParam(':pass', $passe_admin);
			
			$connexion_accepter->execute();
			
			$verif = $connexion_accepter->fetch();
			$verif_mdp = password_verify($passe_admin, '$2y$12$w3g7KNhp3uGacrHC6CvPiOtCdpm6OJ60OrQU5iETzlRnrZ6bPFB4a'); 
			
			if ($verif_mdp == true)
			{
				
				header('Location: aze/index.php');
				
			}
			else
			{
				echo 'Mot de passe incorrect.';
				
			}
			
		}
	}
}
ceci correspond au mot de passe hashé dans la base de données : $2y$12$w3g7KNhp3uGacrHC6CvPiOtCdpm6OJ60OrQU5iETzlRnrZ6bPFB4a et si je veux le récupérer avec cette valeur : $verif_mdp = password_verify($passe_admin, $verif['mdp']); ca ne fonctionne plu....!!!

Je comprend pas de où peut venir l'erreur.
Quelqu'un aurait-il une solution ?

Mammouth du PHP | 688 Messages

23 avr. 2015, 12:13

$passe_admin = htmlspecialchars(trim($_POST['pass']));
essaie sans htmlspecialchars

Mammouth du PHP | 2278 Messages

24 avr. 2015, 09:09

Fais simplement afficher le mot se passe juste avant d'exécuter la requête lors de la tentative de connexion...
$connexion_accepter = $connexion_base_de_donnees->prepare("SELECT * FROM admin WHERE mdp = :pass");
 var_dump($passe_admin);
			$connexion_accepter->bindParam(':pass', $passe_admin);
			
			$connexion_accepter->execute();
			
			$verif = $connexion_accepter->fetch();
//Il devrait suffire de vérifier que $verif contient quelque chose ...
			$verif_mdp = password_verify($passe_admin, '$2y$12$w3g7KNhp3uGacrHC6CvPiOtCdpm6OJ60OrQU5iETzlRnrZ6bPFB4a');
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Eléphanteau du PHP | 23 Messages

24 avr. 2015, 13:41

Re,

J'ai essayé en enlevant htmlspecialchars, ça ne fonctionne pas.

J'ai créer un mot de passe 123456789 puis utiliser var_dump, j'ai cliqué sur connexion et ça m'affiche 123456789, mais ça ne fonctionne toujours pas. ça affiche mon echo pour le message d'erreur.

Aucune des deux solution ne fonctionne.

Autre solution...?

Eléphanteau du PHP | 23 Messages

24 avr. 2015, 16:48

Je ne sais pas si le problème vient d'ici, mais quand je fais : var_dump($verif['mdp']); cela m'affiche null
Je réalise un var_dump à cet endroit du code :
....
$connexion_accepter->execute();
			
			$verif = $connexion_accepter->fetch();
			$verif_mdp = password_verify($passe_admin, $verif['mdp']);
			var_dump($verif['mdp']);
			
			if ($verif_mdp == true)
....

Mammouth du PHP | 2278 Messages

24 avr. 2015, 19:45

$verif = $connexion_accepter->fetch();
var_dump ($verif);
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Eléphanteau du PHP | 23 Messages

24 avr. 2015, 20:21

j'ai fait comme tu m'as dit : $verif = $connexion_accepter->fetch();
var_dump($verif);

ca m'affiche : boolean false

Mammouth du PHP | 688 Messages

24 avr. 2015, 20:26

il faut d'abord vérifier si la requete retourne des résultats, ce qui n'est pas le cas si cela afiche false.

Eléphanteau du PHP | 23 Messages

24 avr. 2015, 20:30

Tu veux je reprenne les lignes du code une à une pour voir à quel moment ça 'bug' ? Et en utilisant des echo, var_dump et print_r ?

Mammouth du PHP | 2278 Messages

25 avr. 2015, 09:11

Si
$verif = $connexion_accepter->fetch();
var_dump ($verif);
donne false; il faut chercher l'erreur avant
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Eléphanteau du PHP | 23 Messages

25 avr. 2015, 09:53

Voici le même code php que j'ai réaliser pour récupérer le pseudo dans la base de données :
<?php
if (isset($_POST['connexion']))
{
	if (empty($_POST['login']))
	{
		echo 'Le login est vide.';
	}
	else
	{
		$passe_admin = htmlspecialchars(trim($_POST['login']));
		
		$connexion_base_de_donnees = new PDO('connexion base de données');
		$connexion_base_de_donnees->exec('SET NAMES utf8');
		
		if (!$connexion_base_de_donnees)
		{
			echo '<font color="red">La connexion au serveur rencontre des difficultées.</font>';
			
		}
		else
		{
			$connexion_accepter = $connexion_base_de_donnees->prepare("SELECT * FROM admin WHERE id_admin = :login");
			$connexion_accepter->bindParam(':login', $passe_admin);
			
			$connexion_accepter->execute();
			
			$verif = $connexion_accepter->fetch();
			if ($verif['id_admin'] == $passe_admin)
			{
				header('Location: aze/index.php');
				
			}
			else
			{
				echo 'Cest pas bon.';
				
			}
		}
	}
}
Ce code ci fonctionne. Il est identique à celui pour récupérer le mot de passe, à une chose près de l'utilisation de password_verify

Eléphanteau du PHP | 23 Messages

25 avr. 2015, 10:12

Le soucis vient probablement du hashage du mot de passe....
Dans ma base de données j'ai comme identifiant bob et mel et voici le début des mots de passe hashé par password_hash $2y$12$
Dans phpmyadmin quand je réalise cette requête :

SELECT * FROM `admin` WHERE `id_admin` = 'bob' => resultat ok (identique pour mel)

Par contre quand je fais cela

SELECT * FROM `admin` WHERE `mdp` = '$2y$12$' => la requête m'affiche aucun résultat alors qu'elle devrait m'afficher bob et mel

Avez_vous une idée à partir de ses informations ?

Eléphanteau du PHP | 23 Messages

25 avr. 2015, 10:18

Normale que cette requete ne fonctionne pas
SELECT * FROM `admin` WHERE `mdp` = '$2y$12$' puisque je ne prend pas le mot de passe en entier.

Donc ça ne vient pas de la.

Autant pour moi.

Eléphanteau du PHP | 23 Messages

26 avr. 2015, 09:39

Je n'ai toujours pas trouvé de solution à mon problème.

Quelqu'un aurait autre chose à me proposer ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

26 avr. 2015, 10:01

Je crois que tu as un problème de logique dans ta page de connexion... Quand tu vas chercher en base la correspondance tu utilises cette requête avec le mot de passe spécifié par l'utilisateur :
$passe_admin = htmlspecialchars(trim($_POST['pass']));
...
$connexion_accepter = $connexion_base_de_donnees->prepare("SELECT * FROM admin WHERE mdp = :pass");
$connexion_accepter->bindParam(':pass', $passe_admin);
Le problème, c'est qu'en base, ce n'est pas le mot de passe de l'utilisateur que tu as stocké, mais le hash :
$passe_admin = htmlspecialchars(trim($_POST['pass']));
$hash = password_hash($passe_admin, PASSWORD_BCRYPT, ['cost' => 12]);
...
$connexion_accepter = $connexion_base_de_donnees->prepare("INSERT INTO admin (mdp) VALUES (:pass)");
$connexion_accepter->bindParam(':pass', $hash);
Ton select ne va donc trouver aucune correspondance et la comparaison de valeur ne donnera rien.


Dans la logique il faudrait soit que fasses une requête basée sur le login pour ramener le mot de passe crypté, et faire ensuite ta verif; ou bien crypter le mot de passe spécifié par l'utilisateur avant de faire la requête (auquel cas tu fais la comparaison en SQL et contrôle qu'il y a bien des résultats) :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...