简体   繁体   中英

user authentication with php class. is this right?

This is my first attempt to create a class.

I created a User class which does login, registration and logout.

It seems it's working but I'm sure I've done something wrong. For example when I only use login() method why do I have to give all variables that I created in ___construct. for login I only need username and password.

I display errors with $_ERROR variable in my template system. How do I display errors in class. I used throw new ExampleException

Could anyone review my class and tell me the mistakes I made please? I just want to learn how to use class...

this is my class

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

}
?> 

and this is how I use it...

<?php

if ( isset( $_POST['Username'] ) )
{
$Username =  trim( $_POST['Username'] );
$Password =  trim( $_POST['Password'] );

if ( !preg_match( '/^[a-z0-9_]+$/i', $Username ) )
    $_ERROR = 'bad username!';
else
{
    $UserClass = new User($dbc, $Username, $Email, $Password, $Salt);

    if($userid = $UserClass->login())
    {
        if ( isset( $_POST['Remember'] ) )
        {
            setcookie( 'UserID', $data['UserID'], time() + 31536000, '/', SITE );
            setcookie( 'PassHash', md5( $data['Password'] .     $data['CookieKey'] ), time() + 31536000, '/', SITE );
        }

        header( "Location: " . ( $_POST['Redirect'] != '' ? base64_decode(     $_POST['Redirect'] ): '/index.php' ) );
        die();
    }
    else
        $_ERROR = "Check your username or password!";
        $_INFO .= $_SESSION['UserID'];

}
}else{

$Reff = '';
if ( isset( $_SERVER['HTTP_REFERER'] ) )
$Reff = base64_encode( $_SERVER['HTTP_REFERER'] );

$_INFO .= $_SESSION['UserID'];
$_PAGE .= t_LoginForm( $Reff );


}

?>

Your using PDO which is always a plus but the problem is that you are not binding your parameters. The biggest plus to PDO is actually binding parameters. In your example :

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

and so on...............

Second part that is scaring me and should scare you if you read up on password security is this that you are using md5 for your passwords with just a random key string called $characters that you just concatenate? That sir... is... just... stupid (sorry for be blunt but this in fact is a big issue and could cause your clients / user massive troubles WHICH IS VERY SERIOUS).

Here try this Bcrypt Library . It is 2013 YOU SHOULD NOT BE USING md5 even with a salt and even with the method that you are doing so :

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

    return $string;

Trust me stay away from building your own "encryption/hashing" methods and use a community trusted method.

Also back to the PDO part, don't forget to add this to your attributes :

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

I hope you learn something from this post. You should not be using PDO without bindParam, and you should not be using MD5 at all with or without a salt. Bcrypt Bcrypt Bcrypt Bcrypt Bcrypt.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM