如何使此功能也适用于用户名或电子邮件?

时间:2012-01-26 17:00:51

标签: php sql function login

我有以下用于检查用户登录的功能,在状态下它只能检查用户名和密码:

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);
            }
        }
    }
}

对所包含的所有函数和其他变量进行抽象,我需要知道是否可以使此函数适用于用户名以及电子邮件。

我的意思是,我想让用户有机会通过他/她的电子邮件或他/她的用户名登录。这可能对我的功能有用吗,如果是的话怎么做?

4 个答案:

答案 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注入(读取它!)。

从现在开始,您可以继续使用代码。