Как заставить эту функцию работать для имени пользователя или электронной почты? - PullRequest
1 голос
/ 26 января 2012

У меня есть следующая функция, которую я использую для проверки имени пользователя, в состоянии он может проверять только имя пользователя и пароль:

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 ]

3 голосов
/ 26 января 2012

Звучит так, как ты хочешь WHERE (user_username = ? OR user_email = ?).

Однако вам потребуется извлечь соль из базы данных.
Рекомендуется использовать в качестве соли длинную последовательность криптографически безопасных случайных байтов, а не имя пользователя, поэтому вам все равно следует это делать.

0 голосов
/ 26 января 2012

Проверьте наличие @ и измените свой запрос соответственно:

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

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

Другая проблема - соль, основанная на имени пользователя. Это, очевидно, не удастся, если пользователь решит перейти на адрес электронной почты. Поскольку было предложено , используйте отдельную соль (не связанную с именем пользователя) и добавьте дополнительный запрос для ее получения.

0 голосов
/ 26 января 2012
$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-инъекций (подробности об этом!).

С этого момента вы можете продолжить работу с кодом.

0 голосов
/ 26 января 2012

Полагаю, вы могли бы изменить запрос, чтобы проверить $ username по обоим полям имени пользователя и электронной почты в базе данных, например что-то вроде

SELECT user_username,user_level
FROM users
WHERE (? IN (user_username, user_email)) AND user_password = ?';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...