我试图创建一个登录,只需要密码访问。我知道了。
/* Validates the login form data, checks if username and password are provided
@return bool Login form data check success state */
private function checkLoginFormDataNotEmpty() {
if (!empty($_POST['user_name']) && !empty($_POST['user_password'])) { return true; }
elseif (empty($_POST['user_name'])) { $this->feedback = "Username field was empty."; }
elseif (empty($_POST['user_password'])) { $this->feedback = "Password field was empty."; }
return false; } // default return
/* Checks if user exits, if so: check if provided password matches the one in the database
@return bool User login success status */
private function checkPasswordCorrectnessAndLogin() {
// remember: the user can log in with username or email address
$sql = 'SELECT user_name, user_email, user_password_hash
FROM users
WHERE user_name = :user_name OR user_email = :user_name
LIMIT 1';
$query = $this->db_connection->prepare($sql);
$query->bindValue(':user_name', $_POST['user_name']);
$query->execute();
// Btw that's the weird way to get num_rows in PDO with SQLite:
// if (count($query->fetchAll(PDO::FETCH_NUM)) == 1) {
// Holy! But that's how it is. $result->numRows() works with SQLite pure, but not with SQLite PDO.
// This is so crappy, but that's how PDO works.
// As there is no numRows() in SQLite/PDO (!!) we have to do it this way:
// If you meet the inventor of PDO, punch him. Seriously.
$result_row = $query->fetchObject();
if ($result_row) {
// using PHP 5.5's password_verify() function to check password
if (password_verify($_POST['user_password'], $result_row->user_password_hash)) {
// write user data into PHP SESSION [a file on your server]
$_SESSION['user_name'] = $result_row->user_name;
$_SESSION['user_email'] = $result_row->user_email;
$_SESSION['user_is_logged_in'] = true;
$this->user_is_logged_in = true;
return true; }
else { $this->feedback = "Wrong password."; } }
else { $this->feedback = "This user does not exist."; }
// default return
return false;
}
所以我删除了与'user_name'相关的东西,直到我得到这个:
/* Validates the login form data, checks if username and password are provided
@return bool Login form data check success state */
private function checkLoginFormDataNotEmpty() {
if (!empty($_POST['user_password'])) { return true; }
elseif (empty($_POST['user_password'])) { $this->feedback = "Password field was empty."; }
return false; } // default return
/* Checks if user exits, if so: check if provided password matches the one in the database
@return bool User login success status */
private function checkPasswordCorrectnessAndLogin() {
// remember: the user can log in with username or email address
$sql = 'SELECT user_name, user_email, user_password_hash
FROM users
LIMIT 1';
$query = $this->db_connection->prepare($sql);
$query->execute();
// Btw that's the weird way to get num_rows in PDO with SQLite:
// if (count($query->fetchAll(PDO::FETCH_NUM)) == 1) {
// Holy! But that's how it is. $result->numRows() works with SQLite pure, but not with SQLite PDO.
// This is so crappy, but that's how PDO works.
// As there is no numRows() in SQLite/PDO (!!) we have to do it this way:
// If you meet the inventor of PDO, punch him. Seriously.
$result_row = $query->fetchObject();
if ($result_row) {
// using PHP 5.5's password_verify() function to check password
if (password_verify($_POST['user_password'], $result_row->user_password_hash)) {
// write user data into PHP SESSION [a file on your server]
$_SESSION['user_name'] = $result_row->user_name;
$_SESSION['user_email'] = $result_row->user_email;
$_SESSION['user_is_logged_in'] = true;
$this->user_is_logged_in = true;
return true; }
else { $this->feedback = "Wrong password."; } }
else { $this->feedback = "This user does not exist."; }
// default return
return false;
}
问题:它工作,但只有在sql数据库的第一个密码。
有什么解决办法吗?我非常感谢你:
@njk2已经发现了这个问题。原因如下,请查看您的查询:
SELECT user_name, user_email, user_password_hash FROM users
这将按可能插入的顺序拉出所有用户的列表。如果你加上LIMIT 1
,那么它只会从这个集合中获取第一行。这将是数据库中的第一个密码。
只看这些,我不认为消除用户名并且仍然想要识别用户(使用$_SESSION['user_name']
)有任何意义。我强烈建议不要这样做,坦率地说,这已经不是最安全的设置了。
即使你禁止冲突(没有用户可以有相同的密码)-那么你仍然使更容易入侵(你不需要知道一个用户的用户名和密码,只需要尝试一个密码列表)。
不考虑建议,理论上您可以通过密码散列进行搜索:
$sql = 'SELECT user_name, user_email, user_password_hash
FROM users
WHERE user_password_hash = :password
LIMIT 1';
$query = $this->db_connection->prepare($sql);
$query->bindValue(':password', password_hash ($_POST['user_password']));