我正在編寫一個使用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 ...
我們不是心理學家根據描述找出代碼。如果您需要幫助,請提供您的代碼。 –