2017-06-29 1 views
0

J'essaie de faire une fonction de changement de mot de passe de compte pour mon site Web. Les codes de connexion fonctionnent correctement, haché les mots de passe avec bcrypt, la connexion vérifie et confirme que le nom du compte et le mot de passe sont corrects avec ceux qui sont entrés. J'essaye d'utiliser le même algorithme pour vérifier la passe actuelle et la vérification de passe de base de données, mais quelque chose semble manquer. Je reçois constamment un hachage différent du mot de passe qui est entré et une mauvaise erreur de mot de passe actuelle.PHP Changer le compte Mot de passe Freins à vérifier le mot de passe actuel

Voici le code exact que j'utilise dans le fichier php.

<?php 
session_start(); 

function test_input($data) { 
    $data = trim($data); 
    $data = stripslashes($data); 
    $data = htmlspecialchars($data); 
    return $data; 
} 

$client_new_password_err = $client_current_password_err = $client_confirm_new_password_err = $general_err = ""; 

try { 
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); 
    // set the PDO error mode to exception 
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $user_check = $_SESSION['login_user']; 
    $stmt = $conn->prepare("SELECT UserName FROM user_main WHERE UserName='$user_check'"); 
    $stmt->execute(); 
    foreach ($stmt->fetch(PDO::FETCH_ASSOC) as $arr) { 
     $login_session = $login_session . $arr; 
    } 
    if (empty($login_session)) { 
     $conn = null; 
     header('Location: login.php'); 
    } 
    $stmt = $conn->prepare("SELECT Email FROM user_main WHERE UserName='$user_check'"); 
    $stmt->execute(); 
    foreach ($stmt->fetch(PDO::FETCH_ASSOC) as $arr) { 
     $login_email = $login_email . $arr; 
    } 
} 
catch(PDOException $e) 
{ 
    echo $stmt . "<br>" . $e->getMessage(); 
} 
$conn = null; 

if ($_SERVER["REQUEST_METHOD"] == "POST") { 
    if (!empty($_POST["current-password"])) { 
     $client_current_password = test_input($_POST['current-password']); 
     $cost = [ 
      'cost' => 11, 
     ]; 
     $client_current_hashed_password = password_hash($client_current_password, PASSWORD_BCRYPT, $cost); 
    } else { 
     $client_current_password_err = "No input on Current Password"; 
    } 
    if (!empty($_POST['new-password'])) { 
     $client_new_password = test_input($_POST['new-password']); 
     $cost = [ 
      'cost' => 11, 
     ]; 
     $client_new_hashed_password = password_hash($client_new_password, PASSWORD_BCRYPT, $cost); 
    } else { 
     $client_new_password_err = "No input on New Password"; 
    } 
    if (!empty($_POST['confirm-new-password'])) { 
     $client_confirm_new_password = test_input($POST['confirm-new-password']); 
     $cost = [ 
      'cost' => 11, 
     ]; 
     $client_confirm_new_hashed_password = password_hash($client_confirm_new_password, PASSWORD_BCRYPT, $cost); 
    } else { 
     $client_confirm_new_password_err = "No input on New Password"; 
    } 
    if ($client_new_hashed_password == $client_confirm_new_hashed_password) { 
     $to_change_pass = 1; // not yet implemented 
    } else { 
     $to_change_pass = 0; // not yet implemented 
    } 
} 

if (!empty($client_current_hashed_password) && !empty($client_new_hashed_password) && !empty($client_confirm_new_hashed_password)) { 
    try { 
     $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); 
     // set the PDO error mode to exception 
     $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     $user_check = $_SESSION['login_user']; 
     $stmt = $conn->prepare("SELECT Password FROM user_main WHERE UserName='$user_check'"); 
     $stmt->execute(); 
     foreach ($stmt->fetch(PDO::FETCH_ASSOC) as $db_hash_pass) { 
      if(password_verify($client_current_password, $db_hash_pass)) { 
       $stmt = $conn->prepare("UPDATE user_main SET Password = '$client_new_hashed_password' WHERE UserName = '$user_check'"); 
      } else { 
        $general_err = "Entered current password does not match the actual password for this account. Please try again."; 
       } 
     } 
    } 
    catch(PDOException $e) 
    { 
     echo $stmt . "<br>" . $e->getMessage(); 
    } 
    $conn = null; 
} 
?> 

La principale question est de savoir comment dois-je vérifier si le courant passe entré correspond à celui sur la base de données? Devrais-je utiliser la version hachée de la carte saisie par le client ou devrais-je utiliser le mot de passe en texte clair?

C'est le mot de passe de connexion vérifier le code qui est 100% opérationnel

if (!empty($_POST['password'])) { 
    if (!preg_match("/^[a-zA-Z0-9 ]*$/",$_POST['password'])) { 
     $usernameErr = 'Only Letters and Numbers'; 
    } else { 
    $client_password = test_input($_POST['password']); 
     if(password_verify($client_password, $hashed_password)) { 
     $_SESSION['login_user'] = $client_username; 
     header("location: profile.php"); 

où hashed_password $ est tiré de la colonne base de données Mot de passe avec correspondance nom d'utilisateur et ici il fonctionne. Comme vous pouvez le voir, j'ai limité les mots de passe aux lettres et aux chiffres - Question supplémentaire: En permettant l'utilisation de tous les caractères dans un mot de passe, est-ce que cela impose un type de menace d'injection?

+0

1. * comment dois-je vérifier si le courant passe entré correspond à celui sur la base de données *: Exactement de la même façon que vous faites lorsque le L'utilisateur se connecte. Ne pas hacher, mais vérifier à la place. 2. no – jeroen

+0

Je fais cela et je reçois un hash différent à chaque fois, et le script $ general_err = "Le mot de passe actuel ne correspond pas au mot de passe pour ce compte. Veuillez réessayer svp."; comme il se doit bien sûr. Cest mon principal problème que le script en ce moment de travail ne marche pas, dans ce que j'ai fait le vérifier si (password_verify (client_current_password de $, db_hash_pass de $)) Où client_current_password est l'entrée brute de l'utilisateur (après être passé par test_input() function) et db_hash_pass est le mot de passe tiré du DB où le nom d'utilisateur correspond ... c'est mon problème –

+0

Note de côté: Vous n'avez pas besoin de cette méthode 'test_input()' personnalisée et je ne sais pas pourquoi vous utilisez cette. Pour votre question "bonus" ne limitez pas les mots de passe. Un tel que '123 '\ ---
DELETE' est parfaitement valide. En utilisant une instruction préparée, 'password_hash/verify()' est suffisant. –

Répondre

0

Ne pas hacher, mais vérifier à la place. - jeroen 13 minutes il y a

Removed hachant à partir du code entièrement et il est ok maintenant, cela fonctionne à l'aide password_verify (client_current_password de $, db_hash_pass de $).

Merci pour JEROEN la poussée u m'a donné à faire: D