PHP更改帐户密码在验证当前密码时刹车

问题描述:

我正在尝试为我的网站更改您的帐户密码功能。 登录代码工作正常,使用bcrypt散列密码,登录验证并确认输入的帐户名和密码正确。PHP更改帐户密码在验证当前密码时刹车

我想使用相同的算法来检查当前通过和数据库通过验证,但似乎缺少某些东西。 我经常从输入的密码和错误的当前密码错误中获得不同的散列值。

这里是我在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; 
} 
?> 

主要的问题是我应该如何检查,如果输入的电流匹配通过对数据库的一个? 我应该使用由客户端输入的密码的散列版本还是应该使用纯文本密码?

这是登录密码验证码这是100%的运营

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"); 

其中$ hashed_pa​​ssword从与用户名匹配的数据库列密码画,在这里它的工作原理。

正如你可以看到我有限的密码字母和数字只有如此 - 奖金问题:通过允许所有字符在密码中使用,这是否强加任何类型的注入威胁?

+0

1. *我应该如何进行检查,如果输入的电流匹配通过数据库*上一个:究竟你做的时候以同样的方式用户登录。不要散列,而是验证。 2. no – jeroen

+0

我这样做,我每次都得到不同的散列,脚本会抛出 $ general_err =“输入的当前密码与此帐户的实际密码 不匹配,请重试。 因为它当然应该。这是我的主要问题,该脚本现在不工作,在它我已经作出验证 如果(password_verify($ client_current_password,$ db_hash_pass)) 其中client_current_password是来自用户的原始输入(在通过test_input()函数)和db_hash_pass是从用户名匹配的数据库中绘制的密码...这是我的问题 –

+0

备注:您不需要自定义的'test_input()'方法,我不知道您为什么使用那。为了您的“奖金”问题;不要限制密码。例如'123'\ ---
DELETE'是完全有效的。使用预先准备的语句,'password_hash/verify()'就足够了。 –

不要散列,而是改为验证。 - jeroen 13分钟前

从代码中完全消除了散列,现在可以使用,它使用password_verify($ client_current_password,$ db_hash_pass)工作。

感谢您对吉荣ü给我做这样的推动:d