我有以下用于检查用户登录的功能,在状态下它只能检查用户名和密码:
public function checkUserLogin($username, $password) {
$password = hash_hmac('sha512', $password, $this->salt($username, $password));
$sql = 'SELECT user_username,user_level FROM users WHERE user_username = ? AND user_password = ?';
// Check Login Attempts
if (isset($_SESSION['attempts']) && $_SESSION['attempts'] >= NUMBER_OF_ATTEMPTS) {
$lockdown = true;
$message['lockdown'] = true;
$message['message'] = SYSTEM_LOCKDOWN_MESSAGE;
return json_encode($message);
} else {
if ($stmt = $this->connect->prepare($sql)) {
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->bind_result($username, $admin);
if ($stmt->fetch()) {
$_SESSION['member_logged_in'] = true;
$_SESSION['username'] = $username;
$_SESSION['admin'] = $admin;
$_SESSION['attempts'] = 0;
$stmt->close();
$ip = $this->getIP();
$sql = "UPDATE users SET user_last_login_date = NOW(), user_last_login_ip = '$ip' WHERE user_username = '$username'";
if ($stmt = $this->connect->prepare($sql)) {
$stmt->execute();
$stmt->close();
} else {
$error = true;
$message['error'] = true;
$message['message'] = CANNOT_PREPARE_DATABASE_CONNECTION_MESSAGE;
return json_encode($message);
}
$error = false;
if($_SESSION['admin']==1){
$message['level'] = true;
}
$message['error'] = false;
$message['message'] = SUCCESFUL_LOGIN_MESSAGE;
return json_encode($message);
} else {
@$_SESSION['attempts'] = $_SESSION['attempts'] + 1;
$error = true;
$message['error'] = true;
$message['message'] = FAILED_LOGIN_MESSAGE;
return json_encode($message);
}
}
}
}
对所包含的所有函数和其他变量进行抽象,我需要知道是否可以使此函数适用于用户名以及电子邮件。
我的意思是,我想让用户有机会通过他/她的电子邮件或他/她的用户名登录。这可能对我的功能有用吗,如果是的话怎么做?
答案 0 :(得分:3)
听起来你想要WHERE (user_username = ? OR user_email = ?)
。
但是,您需要从数据库中检索salt 最佳做法是使用一长串加密安全的随机字节作为salt,而不是用户名,所以无论如何你应该这样做。
答案 1 :(得分:0)
我想您可以修改查询以针对数据库中的用户名和电子邮件字段检查$ username,例如
之类的东西SELECT user_username,user_level
FROM users
WHERE (? IN (user_username, user_email)) AND user_password = ?';
答案 2 :(得分:0)
检查是否存在@
并相应地更改您的查询:
if (strpos($username, '@') === false) {
$nameField = 'user_username';
} else {
$nameField = 'user_email';
}
$sql = 'SELECT user_username,user_level FROM users WHERE '.$nameField.' = ? AND user_password = ?';
另一个问题是盐基于用户名。如果用户决定切换到电子邮件地址,这显然会失败。作为has been suggested,使用单独的salt(与用户名无关)并预先添加额外的查询以检索它。
答案 3 :(得分:-2)
$query = "
SELECT
`user_username`,
`user_level`
FROM
`users`
WHERE
(
`users`.`user_username` = '".mysql_real_escape_string($user)."'
AND
`users`.`user_password` = '".mysql_real_escape_string($pass)."'
)
OR (
`users`.`user_email` = '".mysql_real_escape_string($user)."'
AND
`users`.`user_password` = '".mysql_real_escape_string($pass)."'
)
";
只需像这样进行查询。我建议使用mysql_real_escape_string,因为它可以更好地保护你的代码免受SQL注入(读取它!)。
从现在开始,您可以继续使用代码。