2017-05-05 52 views
-3

我正在編寫一個使用OO PHP的MVC樣式應用程序,並且在嘗試註冊/登錄用戶時嘗試使用不同的類時遇到了問題。基本上,我有一個抽象的用戶類,它包含一些常見的屬性和函數以及兩個擴展它的類:一個用戶嘗試登錄時創建的LoginUser類和一個用戶嘗試註冊時創建的RegisterUser類。從OO中的不同對象使用password_hash和password_verify PHP

我的問題是這樣的:當我使用RegisterUser類中調用的查詢(使用密碼上的password_hash函數)成功地將用戶添加到我的數據庫,然後嘗試通過LoginUser類中調用的查詢進行登錄(使用password_verify函數),即使提供的密碼肯定是在註冊時輸入的密碼,查詢結果也會返回false。

我的問題是這樣的:password_verify函數是否必須由使用password_hash函數創建哈希的同一類的對象調用?如果是這樣,爲什麼?我曾試着查看PHP文檔,搜索結果也不會返回答案!

我問這個問題的原因是因爲如果所有的函數都保存在一個User類而不是繼承的類中,註冊/登錄將會成功。

我的用戶等級:

abstract class User { 

protected $checkedUserName = ''; 
protected $checkedPassword = ''; 

public function __construct($uncheckedUserName, $uncheckedPassword) { 

    $this->checkedUserName = $this->validateAndSanitizeUserName($uncheckedUserName); 
    $this->checkedPassword = $this->validateAndSanitizePassword($uncheckedPassword); 
} 

protected function validateAndSanitizeUserName($uncheckedUserName) { 
    $string = filter_var($uncheckedUserName, FILTER_VALIDATE_EMAIL); // Checks input is an email 
    $string = filter_var($string, FILTER_SANITIZE_EMAIL); // Removes illegal chars 
    $string = filter_var($string, FILTER_SANITIZE_SPECIAL_CHARS); // Removes HTML tags, etc replacing them with char codes 
    return $string; 
} 

protected function validateAndSanitizePassword($uncheckedPassword) { 
    $string = filter_var($uncheckedPassword, FILTER_VALIDATE_REGEXP, ["options"=>["regexp"=>"/(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}/"]]); // Checks the password against the regex on the form 
    $string = filter_var($string, FILTER_SANITIZE_SPECIAL_CHARS); // Removes HTML tags, etc replacing them with char codes 
    return $string; 
} 

protected function checkIfUserExists() { 
    // Set the initial status of user exists 
    $userExists = false; 
    // Open a connection to the database 
    $con = Db::getInstance(); 

    // Prepare the query 
    $checkIfUserExists = $con->prepare("SELECT * FROM users2 WHERE username=?"); 
    //Execute the query with the checked username 
    $checkIfUserExists->execute([$this->checkedUserName]); 
    // Set $userExists dependent on result 
    if($checkIfUserExists->rowCount() !== 0) { 
    $userExists = true; 
    } 
    return $userExists; 
} 

}

我LoginUser類:

class LoginUser extends User{ 

public function __construct($uncheckedUserName, $uncheckedPassword) { 

    parent::__construct($uncheckedUserName, $uncheckedPassword); 
} 

private function getPasswordHashes() { 
    // Only connect to the database when connection is needed 
    $con = Db::getInstance(); 

    // Check if username and password match 
    // Prepare the query 
    $checkUser = $con->prepare("SELECT * from users2 WHERE username = ?"); 
    // Execute the query using an array to bind the parameter to ? 
    $checkUser->execute([$this->checkedUserName]); 

    return $checkUser; 
} 

public function getLogInResult() { 
    // Initialise the results variable 
    $resultsFound = 0; 

    // Only proceed if the username actually exists 
    if($this->checkIfUserExists()) { 

    // Call the function to get the records that match the username 
    $checkUser = $this->getPasswordHashes(); 

    // Check to see if exactly one match was found and verify the password 
    if($checkUser->rowCount() === 1) { // Note this may not work in other databases - it does in MySQL 
     foreach($checkUser as $user) { 
     if(password_verify($this->checkedPassword, $user['passwordHash'])) { 
      $resultsFound++; 
     } 
     } 
    } 
    return $resultsFound; 
} 

}}

我RegisterUser類:

lass RegisterUser extends User{ 

private $checkedFirstName = ''; 
private $checkedLastName = ''; 

public function __construct($uncheckedUserName, $uncheckedPassword, $uncheckedFirstName, $uncheckedLastName) { 

    parent::__construct($uncheckedUserName, $uncheckedLastName); 
    $this->checkedFirstName = $this->sanitizeString($uncheckedFirstName); 
    $this->checkedLastName = $this->sanitizeString($uncheckedLastName); 
} 

private function sanitizeString($uncheckedString) { 
    $string = filter_var($uncheckedString, FILTER_SANITIZE_STRING); 

    return $string; 
} 

private function insertUserDetails() { 
    // Hash the supplied password in preparation for insertion 
    //$hashedPassword = password_hash($this->checkedPassword, PASSWORD_DEFAULT); 

    // Connect to the database 
    $con = Db::getInstance(); 

    // Prepare the query 
    $addUser = $con->prepare("INSERT INTO users2 VALUES (?, ?, ?, ?)"); 

    // Execute the query using an array to bind the parameters 
    $addUser->execute([$this->checkedUserName, password_hash($this->checkedPassword, PASSWORD_DEFAULT), $this->checkedFirstName, $this->checkedLastName]); 

    // Return the result 
    return $addUser; 
} 

public function getRegisterResult() { 
    // Initialise the variable to store the result state 
    $result = false; 

    // Only proceed if the username does not exist 
    if(!($this->checkIfUserExists())) { 
    $addUser = $this->insertUserDetails(); 

    // If the details were successfully added 
    if($addUser->rowCount() === 1) { 
     $result = true; 
    } 
    } 
    return $result; 
} 

}

因此,在完成登記表的情況下,getRegisterResult()函數稱爲新RegisterUser對象上。登錄時,該getLoginResult()函數被調用一個新的LoginUser對象上,但結果返回false ...

+1

我們不是心理學家根據描述找出代碼。如果您需要幫助,請提供您的代碼。 –

回答

0

在回答我的問題,它並不重要的類使用password_hash和password_verify,如果有與匹配密碼來驗證,並從數據庫散列它應該返回一個積極的結果!

問題同__construct()RegisterUser類 - 呼叫到$uncheckedLastName而非$uncheckedPassword,因此密碼通過父被設置在註冊時並沒有什麼密碼字段中提供的,但什麼是在提供姓氏字段!