sqlite登录只读取最后一个密码

时间:2015-09-12 17:06:21

标签: php database sqlite login passwords

我试图创建一个只需要PASSWORD访问的登录。我有这个。

/* Validates the login form data, checks if username and password are provided
@return bool Login form data check success state */
    private function checkLoginFormDataNotEmpty() {
        if (!empty($_POST['user_name']) && !empty($_POST['user_password'])) { return true; }
        elseif (empty($_POST['user_name'])) { $this->feedback = "Username field was empty."; }
        elseif (empty($_POST['user_password'])) { $this->feedback = "Password field was empty."; }
        return false; } // default return


/* Checks if user exits, if so: check if provided password matches the one in the database
@return bool User login success status */

    private function checkPasswordCorrectnessAndLogin() {
        // remember: the user can log in with username or email address
        $sql = 'SELECT user_name, user_email, user_password_hash
                FROM users
                WHERE user_name = :user_name OR user_email = :user_name
                LIMIT 1';
        $query = $this->db_connection->prepare($sql);
        $query->bindValue(':user_name', $_POST['user_name']);
        $query->execute();

        // Btw that's the weird way to get num_rows in PDO with SQLite:
        // if (count($query->fetchAll(PDO::FETCH_NUM)) == 1) {
        // Holy! But that's how it is. $result->numRows() works with SQLite pure, but not with SQLite PDO.
        // This is so crappy, but that's how PDO works.
        // As there is no numRows() in SQLite/PDO (!!) we have to do it this way:
        // If you meet the inventor of PDO, punch him. Seriously.
        $result_row = $query->fetchObject();
        if ($result_row) {
            // using PHP 5.5's password_verify() function to check password
            if (password_verify($_POST['user_password'], $result_row->user_password_hash)) {
                // write user data into PHP SESSION [a file on your server]
                $_SESSION['user_name'] = $result_row->user_name;
                $_SESSION['user_email'] = $result_row->user_email;
                $_SESSION['user_is_logged_in'] = true;
                $this->user_is_logged_in = true;
                return true; }
            else { $this->feedback = "Wrong password."; } }
        else { $this->feedback = "This user does not exist."; }
        // default return
        return false;
    }

所以我删除了与' user_name'相关的内容。直到我得到这个:

/* Validates the login form data, checks if username and password are provided
@return bool Login form data check success state */
    private function checkLoginFormDataNotEmpty() {
        if (!empty($_POST['user_password'])) { return true; }
        elseif (empty($_POST['user_password'])) { $this->feedback = "Password field was empty."; }
        return false; } // default return


/* Checks if user exits, if so: check if provided password matches the one in the database
@return bool User login success status */

    private function checkPasswordCorrectnessAndLogin() {
        // remember: the user can log in with username or email address
        $sql = 'SELECT user_name, user_email, user_password_hash
                FROM users
                LIMIT 1';
        $query = $this->db_connection->prepare($sql);
        $query->execute();

        // Btw that's the weird way to get num_rows in PDO with SQLite:
        // if (count($query->fetchAll(PDO::FETCH_NUM)) == 1) {
        // Holy! But that's how it is. $result->numRows() works with SQLite pure, but not with SQLite PDO.
        // This is so crappy, but that's how PDO works.
        // As there is no numRows() in SQLite/PDO (!!) we have to do it this way:
        // If you meet the inventor of PDO, punch him. Seriously.
        $result_row = $query->fetchObject();
        if ($result_row) {
            // using PHP 5.5's password_verify() function to check password
            if (password_verify($_POST['user_password'], $result_row->user_password_hash)) {
                // write user data into PHP SESSION [a file on your server]
                $_SESSION['user_name'] = $result_row->user_name;
                $_SESSION['user_email'] = $result_row->user_email;
                $_SESSION['user_is_logged_in'] = true;
                $this->user_is_logged_in = true;
                return true; }
            else { $this->feedback = "Wrong password."; } }
        else { $this->feedback = "This user does not exist."; }
        // default return
        return false;
    }

问题:它有效,但只能使用sql数据库中的第一个密码。

请问任何解决方案?我非常感谢你:(

1 个答案:

答案 0 :(得分:1)

@ njk2已经确定了这个问题。这就是原因,请查看您的问题:

 SELECT user_name, user_email, user_password_hash FROM users 

这将按可能的插入顺序提取所有用户的列表。如果你使用LIMIT 1,那么它只抓取该集合的第一行。这只是数据库中的第一个密码。

仅仅考虑这一点,我认为消除用户名并且仍然想要识别用户($_SESSION['user_name'])是没有意义的。 我强烈建议反对它,坦率地说,这已经不是最安全的设置了。

忽略这一点,这种方法首先具有潜在的冲突(如果两个用户拥有相同的密码会发生什么," pass1234"?你怎么能告诉他们他们是谁他们的密码?)。

即使您禁止冲突(没有用户可以使用相同的密码) - 然后您仍然非常容易入侵(您不需要了解用户'用户名和密码,只是为了尝试一个密码列表)。

除了建议,你可以理论上通过密码哈希搜索:

    $sql = 'SELECT user_name, user_email, user_password_hash
            FROM users
            WHERE user_password_hash = :password
            LIMIT 1';
    $query = $this->db_connection->prepare($sql);
    $query->bindValue(':password', password_hash ($_POST['user_password']));