2017-06-29 194 views
0

我正在嘗試爲我的網站更改您的帳戶密碼功能。 登錄代碼工作正常,使用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()'就足夠了。 –

回答

0

不要散列,而是改爲驗證。 - jeroen 13分鐘前

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

感謝您對吉榮ü給我做這樣的推動:d