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

Php 如何使此功能也适用于用户名或电子邮件?,php,sql,function,login,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_use

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

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);
            }
        }
    }
}
对包含在其中的所有函数和其他变量进行抽象,我需要知道是否可以使该函数对用户名和电子邮件都起作用


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

听起来你想
在哪里(user\u username=?或user\u email=?)

不过,您需要从数据库中检索盐。

最佳做法是使用一长串加密安全的随机字节作为salt,而不是用户名,所以无论如何都应该这样做。

听起来你想要
在哪里(user\u username=?或user\u email=?)

不过,您需要从数据库中检索盐。

最佳做法是使用一长串加密安全的随机字节作为salt,而不是用户名,因此您无论如何都应该这样做。

我想您可以修改查询,根据数据库中的用户名和电子邮件字段检查$username,例如

SELECT user_username,user_level
FROM users
WHERE (? IN (user_username, user_email)) AND user_password = ?';

我想您可以修改查询,根据数据库中的用户名和电子邮件字段检查$username,例如

SELECT user_username,user_level
FROM users
WHERE (? IN (user_username, user_email)) AND user_password = ?';
就这样做吧。我建议您使用mysql\u real\u escape\u字符串,因为它可以更好地保护您的代码不受SQL注入的影响(请仔细阅读!)

从这一点开始,您可以继续使用代码

就这样做吧。我建议您使用mysql\u real\u escape\u字符串,因为它可以更好地保护您的代码不受SQL注入的影响(请仔细阅读!)


从这一点开始,您可以继续使用代码。

检查是否存在
@
,并相应地更改查询:

if (strpos($username, '@') === false) {
    $nameField = 'user_username';
} else {
    $nameField = 'user_email';
}

$sql = 'SELECT user_username,user_level FROM users WHERE '.$nameField.' = ? AND user_password = ?';

另一个问题是salt基于用户名。如果用户决定切换到电子邮件地址,这显然会失败。作为,使用单独的salt(与用户名无关)并预先添加一个额外的查询来检索它。

检查是否存在
@
,并相应地更改查询:

if (strpos($username, '@') === false) {
    $nameField = 'user_username';
} else {
    $nameField = 'user_email';
}

$sql = 'SELECT user_username,user_level FROM users WHERE '.$nameField.' = ? AND user_password = ?';


另一个问题是salt基于用户名。如果用户决定切换到电子邮件地址,这显然会失败。例如,使用一个单独的salt(与用户名无关),并在前面添加一个额外的查询来检索它。

最后,要找一个密码正确的人+1对于散列和参数注意你的用户名是区分大小写的,这是许多用户都不希望看到的。谢谢,散列还有更多内容,但这与我的问题无关。你说用户名区分大小写是什么意思?@SLaks:没有证据表明用户名区分大小写。他可能只是在列中使用了不区分大小写的排序规则。@webbiedave:他使用用户名作为salt。除非他的salt函数不区分大小写(这很奇怪),否则用户名是区分大小写的+1对于散列和参数注意你的用户名是区分大小写的,这是许多用户都不希望看到的。谢谢,散列还有更多内容,但这与我的问题无关。你说用户名区分大小写是什么意思?@SLaks:没有证据表明用户名区分大小写。他可能只是在列中使用了不区分大小写的排序规则。@webbiedave:他使用用户名作为salt。除非他的salt函数不区分大小写(这很奇怪),否则用户名是区分大小写的。这是个好主意吗?使用mysql\u real\u escape\u string(),因为我使用mysqli。@罗兰:你说得对;这是个坏主意。他还将密码存储在纯文本中,这是一个更糟糕的想法。布尔逻辑过于复杂。我存储的是散列,而不是实际的过程。我不是在存储我用来散列通行证的盐。伙计们,前后的逻辑是PHP。我只是指“如何使这个功能也适用于用户名或电子邮件?”而不是其他问题,尽管我同意你们的观点。是的,我想我可以用一个不太广泛的问题来回答——就像你们一样。然而,在我看来,这样一个基本问题(没有冒犯罗兰)不应该用简短的SQL来回答。我的观点是,你会在前进的过程中学到这些东西。PS:我是第一个开始打字的人:)这是个好主意吗?使用mysql\u real\u escape\u string(),因为我使用mysqli。@罗兰:你说得对;这是个坏主意。他还将密码存储在纯文本中,这是一个更糟糕的想法。布尔逻辑过于复杂。我存储的是散列,而不是实际的过程。我不是在存储我用来散列通行证的盐。伙计们,前后的逻辑是PHP。我只是指“如何使这个功能也适用于用户名或电子邮件?”而不是其他问题,尽管我同意你们的观点。是的,我想我可以用一个不太广泛的问题来回答——就像你们一样。然而,在我看来,这样一个基本问题(没有冒犯罗兰)不应该用简短的SQL来回答。我的观点是,你会在前进的过程中学到这些东西。PS:我是第一个开始输入:)这一个不起作用,有一个mysqli错误,如果我在其中插入
WHERE(user\u username=?或user\u email=?)
@Roland,参数的数量就错了:你需要添加一个email参数。(当心salt)我现在成功了,我不得不修改salt算法,但它现在可以工作了。谢谢你的提示:)这一个不起作用,有一个mysqli错误,如果我插入
WHERE(user\u username=?或user\u email=?)
@Roland,参数的数量就错了:你需要添加一个email参数。(当心salt)我现在成功了,我不得不修改salt算法,但它现在可以工作了。谢谢你的提示:)