-1

我从 www.phpacademy.org 上发布的名为“Register & Login”的视频教程中复制了一个登录脚本

我的登录页面包含以下代码...


<?php

if (empty($_POST) === false ) {

    $username = $_POST['username'];
    $password = $_POST['password'];

    if (empty($username) === true || empty($password) === true) {
        $error = '<div id="error" style="font-size:16px; font-family: \'Armata\';">Error: You need to enter <u>Username</u> and <u>Password</u>!</div>';
        }
    else if (user_exists($username) === false){
        $error = '<div id="error" style="font-size:16px; font-family: \'Armata\';">Error: We are not able to get username <u>'.$username.'</u>. Please check your entered details.</div>';
        }
    else if (user_active($username) === false){
        $error = '<div id="error" style="font-size:16px; font-family: \'Armata\';">Error: You need to activate your account by confirming your email address.<br> Check inbox and span folder for confirmation email.</div>';
        }
    else if (strlen($password) > 32 || (strlen($password) < 6 ) ) {
        $error = '<div id="error" style="font-size:16px; font-family: \'Armata\';">Error: Your password must be between 6 and 32 characters.</div>';
    }       
    else {
        $login = login($username, $password);
            if ($login === false) {
            $error = '<div id="error" style="font-size:16px; font-family: \'Armata\';">Error: Your Username or Password is incorrect. Please enter correct details.</div>';
            } else {
                $_SESSION['uid'] = $login;
                header ('Location: /home');
                exit ();
            }

        }
}


?>

然后登录表单

我的登录表单功能页面的代码是


<?php

function sanitize($data) {
    return mysql_real_escape_string($data);
}

function user_data($uid){
        $data = array();
        $uid = (int)$uid;
        $func_num_args = func_num_args();
        $func_get_args = func_get_args();

    if ($func_num_args > 0) {
        unset ($func_get_args[0]);

        $fields = '`' . implode ('`,`',$func_get_args) . '`';
        $data = mysql_fetch_assoc(mysql_query("SELECT $fields FROM `users` WHERE `uid` = $uid"));

        return $data;
    }   
}

function user_logged_in() {
    return (isset($_SESSION['uid'])) ? true : false ;
}

function user_exists($username){
    $username = sanitize($username);
    return (mysql_result(mysql_query("SELECT `uid` FROM `users` WHERE `uname` = '$username'"), 0) == 1) ? true : false;
}

function user_active($username){
    $username = sanitize($username);
    return (mysql_result(mysql_query("SELECT `uid` FROM `users` WHERE `uname` = '$username' AND `active` = 1"), 0) == 1) ? true : false;
}

function uid_from_uname($username){
    $username = sanitize($username);
    return mysql_result(mysql_query("SELECT `uid` FROM `users` WHERE `uname` = '$username' "), 0, 'uid');

}

function login($username, $password){
    $uid = uid_from_uname($username);

    $username = sanitize($username);    
    $password = md5($password);

    return (mysql_result(mysql_query("SELECT `uid` FROM `users` WHERE `uname` = '$username' AND `password` = '$password'"), 0) == 1) ? $uid : false ; 
}

?>

在那个视频中,他们在这样的查询中使用了“SELECT COUNT ( user_id)....”,这在我的系统中不起作用。我正在使用 xampp 1.7.7

问题是在我的数据库表的“id=1”、“username=viral.joshi”和“pass=password”的第一行

它允许我输入并且不显示任何错误,第二行的数据是“id=2”、“username=viral4ever”和“pass=password”,当我输入这个 id pass 时,它显示错误找不到用户名永远病毒。

我编辑了第一行的用户名并将其更改为viral4ever,这样我就可以访问了。所以请帮助我访问每一行。我的 db 表的详细信息是“InnoDB”“latin1_swedish_ci”,列详细信息用户名的排序规则是“utf8_bin”,其他的是“utf8_unicode_ci”,两者都是 varchar 可接受的,uid 是 int。请任何人帮助我。

4

3 回答 3

1

这个也可以试试

$username = sanitize($username);
$sql = "SELECT uid FROM users WHERE uname = '$username'";
$result = mysql_query($sql) or die(mysql_error());
if (mysql_num_rows($result) > 0) {
   return true;
} else {
   return false;
}
于 2013-12-13T14:52:24.693 回答
0

那是彻头彻尾的糟糕代码。所有数据库操作都只是假设没有任何事情会失败。这是一个非常非常糟糕的设计。数据库和查询可能一直失败。同样,您的代码似乎从未真正连接到数据库,除非您根本没有显示任何代码。

一个更好、更容易调试的函数版本是:

$username = sanitize($username);
$sql = "SELECT uid FROM users WHERE uname = '$username'";
$result = mysql_query($sql) or die(mysql_error());
if (mysql_num_rows($result) == 0) {
   return false;
} else {
   return true;
}

这将正确处理数据库错误,在需要时为您提供用于调试的实际查询,并正确查找结果,而不假设会有结果。

当然,在更大的方案中,您不应该使用 mysql_ () 函数编写新代码。它们已过时和弃用。如果您刚刚开始,那么假装 mysql_ () 不再存在,并开始使用 mysqli (注意i)或 PDO 代替。

于 2013-07-24T18:27:00.273 回答
0

我已将您的代码改进为更新版本。这个解决方案当然假设数据库表和列的名称是正确的。此外,您必须将“host”、“user”、“pwd”和“name”替换为实际值。

以下三个文件必须位于同一目录中。我只是假设存在另一种创建和管理 HTML 表单本身的代码和平。最好将该代码也放入 LoginForm 中,以便逻辑和表示清楚地分开。由于我不了解整个情况,因此它不会是一个现成的解决方案。

此解决方案要求用户中有一个名为“salt”(不带“)的附加列,并且密码以下面使用的方式保存。md5 不再安全,任何以 md5 为特色的教程都应立即忽略。此散列解决方案使用双盐密码和 sha1 散列算法。

dbconfig.inc.php:

<?php
$host = 'host';
$dbUser = 'user';
$dbPwd = 'pwd';
$dbName = 'name';

LoginForm.class.php:

<?php
require_once(__DIR__.'/LoginDatabase.class.php');

/**
 * Manages the login form..
 * 
 * @author      Jim Martens
 * @copyright   2013 Jim Martens
 * @license     http://www.gnu.org/licenses/lgpl-3.0 GNU Lesser General Public License, version 3
 */
class LoginForm {
    /**
     * Contains the login database object.
     * @var \LoginDatabase
     */
    private $loginDatabase = null;

    /**
     * Contains the read username.
     * @var string
     */
    private $username = '';

    /**
     * Contains the read password.
     * @var string
     */
    private $password = '';

    /**
     * Contains the error text.
     * @var string
     */
    private $errorText = '';

    /**
     * Initializes the login form.
     */
    public function __construct() {
        $this->loginDatabase = new \LoginDatabase();
        $this->run();
    }

    /**
     * Reads the form parameters.
     */
    public function readFormParameters() {
        if (isset($_POST['username'])) $this->username = trim($_POST['username']);
        if (isset($_POST['password'])) $this->password = trim($_POST['password']);
    }

    /**
     * Validates the input.
     */
    public function validate() {
        if (empty($this->username) || empty($this->password)) {
            $this->errorText = 'You need to enter <u>Username</u> and <u>Password</u>!';
            throw new \Exception($this->errorText);
        }
        if (!$this->loginDatabase->userExists($this->username)) {
            $this->errorText = 'A user with the username <u>'.$this->username.'</u> doesn\'t exist. Please check your entered details.</div>';
            throw new \Exception($this->errorText);
        }
        if (!$this->loginDatabase->userIsActive($this->username)) {
            $this->errorText = 'You need to activate your account by confirming your email address.<br> Check inbox and span folder for confirmation email.';
            throw new \Exception($this->errorText);
        }
        if (strlen($this->password) > 32 || (strlen($this->password) < 6 ) ) {
            $this->errorText = 'Your password must be between 6 and 32 characters.';
            throw new \Exception($this->errorText);
        }
        if (!$this->loginDatabase->isLoginValid($this->username, $this->password)) {
            $this->errorText = 'You have entered a wrong password.';
            throw new \Exception($this->errorText);
        }
    }

    /**
     * Finishes the login process.
     */
    public function save() {
        $_SESSION['uid'] = $this->loginDatabase->getUserID($this->username);
    }

    /**
     * Runs the post form procedure.
     */
    private function run() {
        if (!empty($_POST)) {
            $this->readFormParameters();
            try {
                $this->validate();
                $this->save();
            }
            catch (\Exception $e) {
                $error = '<div id="error" style="font-size:16px; font-family: \'Armata\';">Error: '
                    . $this->errorText .'</div>';
                // where should error be displayed?
            }
        }
    }
}
new LoginForm();

这里是 LoginDatabase.class.php:

<?php
/**
 * Manages the login procedure.
 * 
 * @author      Jim Martens
 * @copyright   2013 Jim Martens
 * @license     http://www.gnu.org/licenses/lgpl-3.0 GNU Lesser General Public License, version 3
 */
class LoginDatabase {
    /**
     * Contains the mysqli object.
     * @var \mysqli
     */
    private $mysqli = null;

    /**
     * Contains the database table name.
     * @var string
     */
    private $table = 'users';

    /**
     * Contains the users.
     * @var array
     */
    private $users = array();

    /**
     * Contains the userIDs mapped to the respective names.
     * @var integer[]
     */
    private $userIDsToName = array();

    /**
     * Initializes the login database.
     */
    public function __construct() {
        include('dbconfig.inc.php');
        $this->mysqli = new \mysqli($host, $dbUser, $dbPwd, $dbName);
        if ($this->mysqli->connect_error) {
            die('Connect Error (' . $this->mysqli->connect_errno . ') '
                . $this->mysqli->connect_error);
        }

        $this->cacheQuery();
    }

    /**
     * Closes the connection.
     */
    public function __destruct() {
        $this->mysqli->close();
    }

    /**
     * Returns the userID for an existing user.
     * 
     * @param   string  $username
     * @return  integer
     * 
     * @require userExists($username)
     */
    public function getUserID($username) {
        $username = trim($username);
        return $this->userIDsToName[$username];
    }

    /**
     * Checks if a user exists.
     * 
     * @param   string  $username
     * @return  boolean
     */
    public function userExists($username) {
        $username = trim($username);
        $userExists = false;
        foreach ($this->users as $userID => $user) {
            if ($user['username'] == $username) {
                $userExists = true;
                break;
            }
        }

        return $userExists;
    }

    /**
     * Checks if a user is active.
     * 
     * @param   string  $username
     * @return  boolean
     */
    public function userIsActive($username) {
        $username = trim($username);
        $isActive = $this->userExists($username);

        if ($isActive) {
            $userID = $this->userIDsToName[$username];
            $user = $this->users[$userID];
            $isActive = $user['isActive'];
        }

        return $isActive;
    }

    /**
     * Checks if the login is valid.
     * 
     * @param   string  $username
     * @param   string  $password
     * @return  boolean
     */
    public function isLoginValid($username, $password) {
        $username = trim($username);
        $password = trim($password);

        $loginValid = $this->userIsActive($username);
        if ($loginValid) {
            $userID = $this->userIDsToName[$username];
            $user = $this->users[$userID];
            $salt = $user['salt'];
            $hashedPassword = sha1($password . sha1($password.$salt));
            $loginValid = ($hashedPassword == $user['password']);
        }

        return $loginValid;
    }

    /**
     * Reads all users from database.
     */
    private function cacheQuery() {
        $sql = 'SELECT uid, uname, password, salt, active
                FROM   '.$this->table;
        if ($result = $this->mysqli->query($sql, MYSQLI_USE_RESULT)) {
            /* @var $result mysqli_result */
            while ($row = $result->fetch_assoc() !== NULL) {
                $row = array(
                    'userID' => intval($row['uid']),
                    'username' => $row['uname'],
                    'password' => $row['password'],
                    'salt' => $row['salt'],
                    'isActive' => (boolean) $row['active']
                );
                $this->users[$row['userID']] = $row;
                $this->userIDsToName[$row['username']] = $row['userID'];
            }

            $result->free();
        }
    }
}
于 2013-07-24T19:30:11.830 回答