我有以下用于处理用户登录的php函数。这些函数是User类的一部分。
/*
* detail() function to get a detail from a database
* exists() function to check if something exists in a database
*/
private function generate($password, $username = null) {
if(is_null($username)) {
$date = '0000-00-00';
} else {
$date = $this->_db->detail('last_active', 'users', 'username', $username);
}
// This is not the real thing but it will do as an example
$salt = md5(strrev($password.$date));
$password = md5($salt.$password.$date).strrev($password);
return $password;
}
public function login($data = array()) {
// Check if the user exists
$username = $data['username'];
if($this->_db->exists('username', 'users', 'username', $username)) {
$password = $this->generate($data['password'], $username);
// If the account is active
if ($this->_db->detail('active', 'users', 'username', $username) === 1) {
$stmt = $this->_db->mysqli->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ? AND `active` = 1");
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows >= 1) {
// Function to update last_active
if($this->updateLastActive($username)) {
// Function to update password
if($this->updatePassword($username, $this->generate($password, $username))) {
// Set the session
$this->_session->set('user', $this->_db->detail('id', 'users', 'username', $username));
if($this->_session->exists('user')) {
return true;
} else {
echo 'Logging in went wrong';
return false;
}
} else {
echo 'Editing the password went wrong';
return false;
}
} else {
echo 'Editing last active date went wrong';
return false;
}
} else {
echo 'Wrong username and password combination';
return false;
}
} else {
echo 'Account not active';
return false;
}
} else {
echo 'Username doesn\'t exists';
return false;
}
}
private function updateLastActive($username) {
$date = date('Y-m-d');
$stmt = $this->_db->mysqli->prepare("UPDATE `users` SET `last_active` = ? WHERE `username` = ?");
$stmt->bind_param('ss', $date, $username);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
private function updatePassword($username, $password) {
$stmt = $this->_db->mysqli->prepare("UPDATE `users` SET `password` = ? WHERE `username` = ?");
$stmt->bind_param('ss', $password, $username);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
用户刚刚注册时可以毫无问题地登录。但是当用户注销并尝试再次登录时,它将失败。我收到错误的部分如下:
$stmt = $this->_db->mysqli->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ? AND `active` = 1");
我尝试在函数的不同位置找出脚本在echo
处失败的位置,但我无法找到错误。 generate()
函数具有$username = null
的原因是因为相同的函数用于注册。
所以所有函数都在工作,但它们只能工作一次所以这让我觉得generate()
函数中的某些函数是错误的。我总是得到用户名/密码组合有问题的消息
如果有人能指出我正确的方向,我会非常高兴。
提前致谢
更新
detail()
和exists()
函数是类Database的一部分。
public function detail($detail, $table, $column, $value) {
if(is_array($detail)) {
$data = array();
foreach($detail as $key) {
$stmt = $this->mysqli->prepare("SELECT `$key` FROM `$table` WHERE `$column` = ?");
if(is_numeric($value)) {
$stmt->bind_param('i', $value);
} else {
$stmt->bind_param('s', $value);
}
$stmt->execute();
$stmt->bind_result($detail);
$stmt->fetch();
$data[] = $detail;
$stmt = null;
}
return $data;
} else {
$stmt = $this->mysqli->prepare("SELECT `$detail` FROM `$table` WHERE `$column` = ?");
if(is_numeric($value)) {
$stmt->bind_param('i', $value);
} else {
$stmt->bind_param('s', $value);
}
$stmt->execute();
$stmt->bind_result($detail);
$stmt->fetch();
return $detail;
}
}
public function exists($detail, $table, $column, $value) {
$stmt = $this->mysqli->prepare("SELECT `$detail` FROM `$table` WHERE `$column` = ?");
switch(is_numeric($value)) {
case true:
$stmt->bind_param('i', $value);
break;
case false:
$stmt->bind_param('s', $value);
break;
}
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows >= 1) {
return true;
} else {
return false;
}
}
答案 0 :(得分:1)
在表格中创建一个哈希字段,使其足够长以避免长度问题。
md5()
现在不被接受,您应该使用更好的哈希函数,例如password_hash()
<强>注册强>
private function register($username, $password) {
//safer than md5() anyway
$hash = password_hash($password, PASSWORD_DEFAULT);
$sql = 'INSERT INTO table_name (`username`, `hash`) VALUES (?, ?);'
$stmt = $this->_db->mysqli->prepare($sql);
$stmt->bind_param('ss', $username, $hash);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
登录:
public function login($username, $password) {
// Check if the user exists
if($this->_db->exists('username', 'users', 'username', $username)) {
// If the account is active
if ($this->_db->detail('active', 'users', 'username', $username) === 1) {
$sql = 'SELECT `username`, `hash` FROM `users` WHERE `username` = ? AND `active` = 1';
$stmt = $this->_db->mysqli->prepare();
$stmt->bind_param('ss', $username, $hash);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows === 1) {
if (password_verify($password, $hash)) {
// Function to update last_active
if($this->updateLastActive($username)) {
echo 'last active updated, Login successful';
return true;
} else {
echo 'Editing last active date went wrong';
return false;
}
} else {
echo 'Wrong username and password combination';
return false;
}
} else {
echo 'Account not active';
return false;
}
} else {
echo 'Username doesn\'t exists';
return false;
}
}
}
当然你仍然可以使用自定义盐,例如
$hash = password_hash($password
,PASSWORD_DEFAULT
,array('salt' =>generate()));//generate() returns the salt