使用php类进行用户身份验证。是这样吗?

使用php类进行用户身份验证。是这样吗?,php,mysql,oop,class,error-handling,Php,Mysql,Oop,Class,Error Handling,这是我第一次尝试创建一个类 我创建了一个用户类,用于登录、注册和注销 它似乎起作用了,但我肯定我做错了什么。例如,当我只使用login()方法时,为什么我必须给出我在__构造中创建的所有变量。登录我只需要用户名和密码 在我的模板系统中,我使用$\错误变量显示错误。如何在课堂上显示错误。我曾经抛出新的ExampleException 有人能复习一下我的课,告诉我我犯的错误吗?我只是想学习如何使用课堂 这是我的课 <?php class User { var $Username = '';

这是我第一次尝试创建一个类

我创建了一个用户类,用于登录、注册和注销

它似乎起作用了,但我肯定我做错了什么。例如,当我只使用login()方法时,为什么我必须给出我在__构造中创建的所有变量。登录我只需要用户名和密码

在我的模板系统中,我使用$\错误变量显示错误。如何在课堂上显示错误。我曾经抛出新的ExampleException

有人能复习一下我的课,告诉我我犯的错误吗?我只是想学习如何使用课堂

这是我的课

<?php
class User
{

var $Username = '';
var $Email = '';
var $Password = '';
var $Salt = '';

protected $_username;
protected $_email;
protected $_password;
protected $_salt;

protected $_db;
protected $_user;

public function __construct(PDO $db, $Username, $Email, $Password, $Salt)
{
    $this->_db = $db;
    $this->_username = $Username;
    $this->_email = $Email;
    $this->_password = $Password;
    $this->_salt = $Salt;

}

private function saltString($Password) // Creates random string for password
{
    $Characters = 'PEcN0';
    $string = md5( $Password . $Characters );

    return $string;
}

public function login() // checks if CheckCredentials is true. if it's true it creates sessions
{
    $user = $this->_CheckCredentials();
    if($user){
        $this->_user = $user;
        $_SESSION['UserID'] = $user['UserID'];
        $_SESSION['Username'] = $user['Username'];
        $_SESSION['Level'] = $user['Level'];
        $_SESSION['Reputation'] = $user['Reputation'];
        return $user['UserID'];
    }
    return false;
}

public function register() // checks if addUser is true.
{
    $user = $this->_addUser();
    if($user){
        $this->createSession($user);    
    }
    return false;
}

public function _CheckCredentials() // checks password and username for login method
{
    $sql = $this->_db->query("SELECT * FROM users WHERE Username = '" . $this->_username . "'");

    if($sql->rowCount() > 0){
        $user = $sql->fetch(PDO::FETCH_ASSOC);
        $pass = $this->saltString($this->_password);
        if($pass == $user['Password']){
            $sql = $this->_db->query( "UPDATE users SET LastLogin = NOW() WHERE UserID = '" . $user['UserID'] . "'" );
            return $user;
        }
    }
    return false;
}

public function _addUser() // add user into database
{
    $sql = $this->_db->query( "SELECT * FROM users WHERE Username = '" . $this->_username . "' OR Email = '" . $this->_email . "'" );
    if($sql->rowCount()){
        $user = $sql->fetch(PDO::FETCH_ASSOC);
        if($user['Username'] == $this->_username){
            throw new ExampleException("This username was taken.");
        }else{
            throw new ExampleException("This e-mail address is being used.");
        }
    }else{
        $intert = $sql->query( "INSERT INTO users ( UserID, OauthUid, OauthProvider, Username, Password, Email, CookieKey, Level, Registered, LastLogin, Reputation, Contents )
        VALUES ( NULL, '". $UserID ."', '". $Provider ."', '" . $Username . "', '" . $Password . "', '" . $Email . "', '" . generateKey( 5 ) . "', '1', NOW(), NOW(), '0', '0')" );

        $UserID = $sql->lastInsertId();

        if($instert){
            $_SESSION['UserID'] = $UserID;
            $_SESSION['Username'] = $Username;
            $_SESSION['Level'] = '1';
        }
    }
    return false;

}

public function getUser()
{
    return $this->_username;
}

}
?> 

您使用的PDO总是一个加号,但问题是您没有绑定参数。PDO最大的优点实际上是绑定参数。在您的示例中:

$sql->bindParam(':userid',$UserID);
$sql->bindParam(':provider',$Provider);
等等

第二部分让我感到害怕,如果你读过密码安全性,应该会让你感到害怕的是,你使用md5作为你的密码,只是一个名为$characters的随机密钥字符串,你只是连接起来?那个先生。。。是只是愚蠢(很抱歉直言不讳,但事实上这是一个大问题,可能会给您的客户/用户带来严重的麻烦)

试试这个。现在是2013年,您不应该使用md5,即使使用盐,即使使用您正在使用的方法:

 $Characters = 'PEcN0';
    $string = md5( $Password . $Characters );

    return $string;
相信我远离构建您自己的“加密/哈希”方法,使用社区信任的方法

同样回到PDO部分,不要忘记将其添加到属性中:

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);

我希望你能从这篇文章中学到一些东西。您不应该在没有bindParam的情况下使用PDO,也不应该在有盐或无盐的情况下使用MD5。Bcrypt Bcrypt Bcrypt Bcrypt Bcrypt Bcrypt.

谢谢,我已经在配置文件中添加了属性。你所说的社区信任方法是什么意思。人们通常做什么?是的,这是正确的。如果你去图书馆链接,你会看到有多少人在使用它。通过谷歌搜索bcrypt-php,您将看到使用bcrypt更应该被视为一种标准,而不是一种最佳实践。Bcrypt密码安全性比me5安全得多。同时也要意识到,当我说community trusted时,我指的是那些不使用自己的密码保护方案的人。并使用bcrypt库。还有更多,而不仅仅是我链接到的那个。我只是用它来提高兼容性非常感谢你。因为这个问题被否决了,我不能再问这个问题了。没问题,按照我发布的指导原则加上验证+过滤,并避开所有用户输入的数据。祝你好运。为什么人们会对此投反对票?我没有做错任何事。不要仅仅因为你不喜欢编码或问题就否决别人
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);