我找不到代码中的错误在哪里

时间:2014-11-03 08:03:33

标签: php mysqli

我正在创建一个简单的resister表单(resister.php),一个登录表单(login.php),并在php和checklogin.php中检查经过身份验证的用户(MySQL)。所有php文件都正常工作,checklogin.php除外。每当我在login.php文件中放入用户名和密码(存​​在于用户表中)时,它会显示警告消息(“密码不正确!”),而应将用户重定向到经过身份验证的主页(home.php )。

resister.php

<!DOCTYPE html>
<html> 
    <head> 
        <title>My first PHP website</title> 
    </head> 
    <body> 
        <h2>Registration Page</h2> 
        <a href="index.php">Click here to go back</a><br/><br/> 
        <form action="register.php" method="post"> 
            Enter Username: <input type="text" name="username" required="required" /><br/><br/>
            Enter Password: <input type="password" name="password" required="required" /><br/><br/> 
            <input type="submit" value="Register" /> 
        </form> 
    </body> 
</html> 

<?php

$con = mysqli_connect("localhost", "root","") or die(mysqli_error()); // Connect to server 
mysqli_select_db($con,'first_db') or die("Cannot connect to database"); // Connect to database 

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $username = mysqli_real_escape_string($con, $_POST['username']); 
    $password = mysqli_real_escape_string($con, $_POST['password']); 
    $bool = true; 

    $query = mysqli_query($con,"Select * from users"); //Query the users table 
    while ($row = mysqli_fetch_array($query)) { //display all rows from query 
        $table_users = $row['username']; // the first username row is passed on to $table_users, and so on until the query is finished 
        if ($username == $table_users) { // checks if there are any matching fields 
            $bool = false; // sets bool to false 
            print '<script>alert("Username already exist!");</script>'; // Prompts the user 
            print '<script>window.location.assign("register.php");</script>'; // redirects to register.php 
        } 
    } 

    if ($bool) { // checks if bool is true 
        mysqli_query($con, "INSERT INTO users (username, password) VALUES ('$username','$password')"); //Inserts the value to table users 
        print '<script>alert("Successfully Registered!");</script>'; // Prompts the user 
        print '<script>window.location.assign("register.php");</script>'; // redirects to register.php 
    } 
} 

?>

此代码工作正常。当我输入用户名和密码时,它存储在数据库(first_db)和表(用户)中。

现在让我们来看看login.php文件。此文件用于登录。

<!DOCTYPE html>
<html>
    <head>
        <title>My first PHP Website</title>
    </head>
    <body>
        <h2>Login Page</h2>
        <a href = "index.php">Click here to go back</a><br/><br/>
        <form action="checklogin.php" method="POST">
            Enter Username: <input type="text" name="username" required="required" /> <br/><br/>
            Enter password: <input type="password" name="password" required="required" /> <br/><br/>
            <input type="submit" value="Login"/>
        </form>
    </body>
</html>

Blow是用于身份验证的文件(checklogin.php)。每当我输入用户名和密码(已重新注册并存储在数据库表中)时,它会提醒消息(“密码不正确!”)。

    <?php 

       $con = mysqli_connect("localhost", "root","") or die(mysqli_error()); //Connect to server 
        mysqli_select_db($con,"first_db") or die("Cannot connect to database"); //Connect to database 

        session_start(); 
        $username = mysqli_real_escape_string($con,$_POST['username']); 
        $password = mysqli_real_escape_string($con,$_POST['password']); 



        $query = mysqli_query($con,"SELECT * from users WHERE username='$username'"); //Query the users table if there are matching rows equal to $username 
        $exists = mysqli_num_rows($query); //Checks if username exists 
        $table_users = ""; 
        $table_password = ""; 
        if($exists > 0) //IF there are no returning rows or no existing username 
        { 
            while($row = mysqli_fetch_array($query)) //display all rows from query 
            { 
                $table_users = $row['username']; // the first username row is passed on to $table_users, and so on until the query is finished 
            $table_password = $row['password']; // the first password row is passed on to $table_users, and so on until the query is finished 
            } 
            if(($username == $table_users) && ($password == $table_password)) // checks if there are any matching fields 
            { 
                    if($password == $table_password) 
                    { 
                        $_SESSION['users'] = $username; //set the username in a session. This serves as a global variable 
                        header("location: home.php"); // redirects the user to the authenticated home page 
                    } 
            }    

            else 
            { 
                Print '<script>alert("Incorrect Password!");</script>'; //Prompts the user 
                Print '<script>window.location.assign("login.php");</script>'; // redirects to login.php 
            } 


            } 
        else 
        { 
            Print '<script>alert("Incorrect Username!");</script>'; //Prompts the user 
            Print '<script>window.location.assign("login.php");</script>'; // redirects to login.php 
        }

     ?>

1 个答案:

答案 0 :(得分:0)

我不知道这是否能解决您的问题,但我想指出您的代码存在的一些问题:

resister.php

$query = mysqli_query($con,"Select * from users");
while ($row = mysqli_fetch_array($query)) {
    $table_users = $row['username'];
    if ($username == $table_users) {
        $bool = false;
        print '<script>alert("Username already exist!");</script>';
        print '<script>window.location.assign("register.php");</script>';
    } 
} 
if ($bool) {
    mysqli_query($con, "INSERT INTO users (username, password) VALUES ('$username','$password')");
    ...
} 

您使用一个查询在数据库中搜索重复的用户名,然后您发出第二个查询以插入新用户。这为两个用户同时注册相同的用户名留下了足够的空间。在繁忙的网站上,这不太可能发生。

解决此问题的规范方法是生成usernameUNIQUE,并尝试插入新用户名。如果新用户名是重复的,则MySQL服务器将以error code 1062回复。

$query = mysqli_query ($con, "INSERT INTO users (username, password) VALUES ('$username', '$password')");
if ($query) {
  // Success
} else if (mysqli_errno ($con) === 1062) {
  // Duplicate username
} else {
  // Other database error
}

checklogin.php

$username = mysqli_real_escape_string($con,$_POST['username']); 
$password = mysqli_real_escape_string($con,$_POST['password']); 
...
$table_users = $row['username'];
$table_password = $row['password'];
...
if(($username == $table_users) && ($password == $table_password))
{ 
  if($password == $table_password) 

请注意,您要将已转义的$username$password转义的$tables_users$table_password进行比较。如果您的用户名或密码中包含不常见的字符,则会导致检查失败。 (为什么要两次比较密码?)

resister.php也有同样的错误。


$query = mysqli_query($con,"SELECT * from users WHERE username='$username'");
$exists = mysqli_num_rows($query);
...
if($exists > 0) { 
  while($row = mysqli_fetch_array($query)) { 
    $table_users = $row['username'];
    $table_password = $row['password'];
  } 
  if(($username == $table_users) && ($password == $table_password)) { 
    if($password == $table_password) { 
      $_SESSION['users'] = $username;
      header("location: home.php");
    } 
...

首先,您要遍历数据库结果,直到找到最后一个。从逻辑上讲,应该只有一个匹配。如果是这样,您可以将while()更改为if()

但是如果表中有重复的用户名,resister.php可以使用,则只测试最后一个结果的密码。您可以通过将密码测试移到while()循环中来解决此问题:

  while($row = mysqli_fetch_array($query)) { 
    $table_users = $row['username'];
    $table_password = $row['password'];

    if(($username == $table_users) && ($password == $table_password)) { 
      if($password == $table_password) { 
        $_SESSION['users'] = $username;
        header("location: home.php");
      }
    }

或者,更简单的是,将密码测试添加到查询本身:

$query = mysqli_query($con,"SELECT * from users WHERE username='$username'" AND password='$password');
if ($query) {
  if (mysqli_num_rows ($query)) {
    // Success
  } else {
    // Wrong username or password
  }
} else {
  // Database error
}

其他问题

$username = mysqli_real_escape_string($con, $_POST['username']); 
$password = mysqli_real_escape_string($con, $_POST['password']); 

正确转出用户数据。这很好。但是,将明文密码存储在数据库中被认为是不好的做法。通常,您将计算密码的哈希值,并仅存储和比较哈希值。请参阅:PHP的Safe Password Hash FAQ