为什么私人主页不是私人通过会话/登录变量



我有一个登录页面,在用户输入有效的用户名/登录后重定向到一个私人主页。我通过会话变量将主页设置为私有-如果会话变量设置(意味着用户已经提交了正确的登录信息),那么它是可见的。如果会话变量没有设置(!isset),页面应该是私有的,并重定向回登录页面。但是,如果用户没有登录,主页不会显示为私有的,并且会直接跳转到登录页面。

登录页面PHP &HTML

<?php
session_start();
require_once("../inc_files/Lesson_5_DB_Connection.php"); 
error_reporting(E_ALL);
ini_set('display_errors', 1);
$error_message= "";
$user_name = "";
$user_password= "";
$member_name="";
$member_id="";
if (isset($_POST['submit'])) {
    $user_name = $_POST['user'];
    $user_password= $_POST['pass'];

    // ADD QUERY TO CHECK IF USER/PASS COMBO IS CORRECT
    if(!empty($user_name) && !empty($user_password)) {
        $query = "SELECT * FROM employees WHERE username='$user_name' and password='$user_password'";
        $result = mysqli_query($dbc, $query)
            or die ('Error querying username/password request');
        if(mysqli_num_rows($result) == 1) {
            $_SESSION['member_name'] = $member_name;
            $_SESSION['member_id'] = $member_id;

            header("Location: /LESSON5/3%20-%20HOMEPAGE%20:%20WELCOME.php");
            exit;
        } // end if rows
        else {
            $error_message = "You were not able to log in";
        } // end else
        // Direct to other webpage
    } // end query
} // end isset
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
    <title>Login</title>
    <link type="text/css" rel="stylesheet" href="/LESSON5/5_Signup_CSS.css">
    </head>
    <body>
    <h1>Welcome to my website!</h1>
    <h2>Please login below.</h2>
    <h3>Don't have an account? <a href="/LESSON5/2%20-%20CREATE%20AN%20ACCOUNT.php">Create one here.</a></h3>
    <div class="formFormat" >  
    <div  id="table1">
    <form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
      <table id="cssTable">
        <tr>
            <td>Username:</td><td><input type="text" id="user" name="user" value="<?php echo $user_name;?>" /></td>
        </tr>
        <tr>
            <td>Password:</td><td><input type="text" id="pass" name="pass" value="<?php echo $user_password;?>"/></td>
        </tr>
          </table>
      </div>
      <div id="table2">
      <table> 
      <tr>
         <td><input type="submit" name="submit"/></td>
       </tr>
       <tr>
          <td id="createAccount"><a href="/LESSON5/2%20-%20CREATE%20AN%20ACCOUNT.php">Create an account</a></td>
       </tr>
       <tr>
        <td><p><?php echo $error_message?></p></td>
       </tr>
      </table>
      </form>
      </div>
    </div> 
    <?php
      mysqli_close($dbc);
    if(isset($_SESSION['user']) && isset($_SESSION['pass'])) {
    echo "Sessions are set";
    }
    else { 
      echo "Not set.";
    }
    ?>
    </body>
    </html>

会话变量$_SESSION['member_name'] = $member_name &在登录页面提交时没有设置$_SESSION['member_id'] = $member_id,我不知道为什么。

这里,如果会话变量没有设置(通过!isset),主页应该重定向到登录,而不显示主页。在这里,假设没有设置上述代码中的会话变量,并且主页没有正确读取PHP脚本并将主页设置为公共,那么这就不起作用了。

PHP

首页

<?php
session_start();
require_once("../inc_files/Lesson_5_DB_Connection.php");
$member_name="";
$member_id="";
if(!isset($_SESSION['member_name']) && !isset($_SESSION['member_id'])) {
    header("Location: /LESSON5/1%20-%20LOGIN.php");
}
?>

我知道有一个错误在$_SESSION变量,但我无法找出差距在哪里。对此的任何意见将不胜感激。

您需要使用mysqli_fetch_assoc()从查询中获取结果

http://php.net/manual/en/mysqli-result.fetch-assoc.php

下面是相同的代码,只是添加了fetch_assoc()并分配给会话变量:
    <?php
session_start();
require_once("../inc_files/Lesson_5_DB_Connection.php"); 
error_reporting(E_ALL);
ini_set('display_errors', 1);
$error_message= "";
$user_name = "";
$user_password= "";
$member_name="";
$member_id="";
if (isset($_POST['submit'])) {
    $user_name = $_POST['user'];
    $user_password= $_POST['pass'];

    // ADD QUERY TO CHECK IF USER/PASS COMBO IS CORRECT
    if(!empty($user_name) && !empty($user_password)) {
        $query = "SELECT * FROM employees WHERE username='$user_name' and password='$user_password'";
        $result = mysqli_query($dbc, $query)
            or die ('Error querying username/password request');
        if(mysqli_num_rows($result) == 1) {
            while ($row = mysqli_fetch_assoc($result)) {
                $_SESSION['member_name'] = $row['member_name'];
                $_SESSION['member_id'] = $row['member_id'];
            }
            header("Location: /LESSON5/3%20-%20HOMEPAGE%20:%20WELCOME.php");
            exit;
        } // end if rows
        else {
            $error_message = "You were not able to log in";
        } // end else
        // Direct to other webpage
    } // end query
} // end isset
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
    <title>Login</title>
    <link type="text/css" rel="stylesheet" href="/LESSON5/5_Signup_CSS.css">
    </head>
    <body>
    <h1>Welcome to my website!</h1>
    <h2>Please login below.</h2>
    <h3>Don't have an account? <a href="/LESSON5/2%20-%20CREATE%20AN%20ACCOUNT.php">Create one here.</a></h3>
    <div class="formFormat" >  
    <div  id="table1">
    <form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
      <table id="cssTable">
        <tr>
            <td>Username:</td><td><input type="text" id="user" name="user" value="<?php echo $user_name;?>" /></td>
        </tr>
        <tr>
            <td>Password:</td><td><input type="text" id="pass" name="pass" value="<?php echo $user_password;?>"/></td>
        </tr>
          </table>
      </div>
      <div id="table2">
      <table> 
      <tr>
         <td><input type="submit" name="submit"/></td>
       </tr>
       <tr>
          <td id="createAccount"><a href="/LESSON5/2%20-%20CREATE%20AN%20ACCOUNT.php">Create an account</a></td>
       </tr>
       <tr>
        <td><p><?php echo $error_message?></p></td>
       </tr>
      </table>
      </form>
      </div>
    </div> 
    <?php
      mysqli_close($dbc);
    if(isset($_SESSION['user']) && isset($_SESSION['pass'])) {
    echo "Sessions are set";
    }
    else { 
      echo "Not set.";
    }
    ?>
    </body>
    </html>

您声明member_name和member_id未设置,这是因为您在运行查询时从未从数据库中获取过它们的数据。您需要获取查询的关联数组,并将它们分配给会话。因为您没有这样做,所以它使用了您在顶部定义的值,这些值为空:

$member_name="";
$member_id="";

这就是为什么它们是空的,因为它们是空的。

我看到了你所做的其他事情。你的文件名中有空格(例如:%20),它们应该被下划线替换。虽然它会起作用,但你会给自己带来未来的头痛。看起来你的密码是明文的。你应该像20年前那样使用加密密码(例如:bCrypt)。你真的不需要在你的代码中设置error_reporting或ini_set,它应该在你的服务器配置(即:php.ini)中根据你的环境进行配置。你不应该使用通配符(例如:SELECT *),而应该声明你需要处理的列。

我还将在查询中添加LIMIT 1。只有当你的账户注册/注册代码有缺陷时,你才能获得1个以上的匹配用户。

恶意代码可能被添加到页面,因为您将用户名/密码回显到页面上而没有对其进行消毒。

你正在使用mysqli,这是一个很好的开始,但是你在你的查询中使用了未消毒的它们。当使用来自用户的数据时,应该先使用准备好的语句或使用mysqli_real_escape_string()。仅仅使用mysql并不能保护你。

总之,如果你使用像Yii这样的框架,你会省去很多麻烦-登录和注册都是为你做的,密码上有加密,以及使用框架的数百个其他原因:)Yii只是我最喜欢的,但任何框架都会帮助任何程序员。我已经很长时间没有处理会话或登录/注册代码了…

添加

在会话中添加表中的更多值:

while ($row = mysqli_fetch_assoc($result)) {
    $_SESSION['member_name'] = $row['member_name'];
    $_SESSION['member_id'] = $row['member_id'];
    // add everything you want from your table
    $_SESSION['employeeId'] = $row['employeeId'];
    $_SESSION['anotherColumn'] = $row['anotherColumn'];
}

最终认为

看起来你有点乱。我认为你需要从头开始用这个php代码。查看数据库中的表,确保它尽可能整洁。列名是有意义的,等等。然后重新制作这个php文件来登录。

您所需要做的就是验证用户。您不需要在会话中存储关于用户的所有信息。一旦会话过期,PHP自己就会终止会话(关闭浏览器,或者按照PHP的默认会话时间限制)。正确配置的服务器可以自己处理会话。因此,您所要做的就是验证它们,并在会话中存储基本数据。

确认用户和密码后,只需将其用户id存储在会话中。然后在每个页面的顶部有一个函数来获取他们在页面上使用的用户数据:

function getUserData($id) {
    $query = "SELECT * FROM users WHERE id = $id LIMIT 1";
    $result = mysqli_query($dbc, $query);
    if ( $result ) {
        if(mysqli_num_rows($result) == 1) {
            $row = mysqli_fetch_assoc($result);
            return $row;
        }
    }
    return false;
}
$userData = getUserData($_SESSION['user_id']);
if ( ! $userData ) {
    die('Error: User data not found!');
}
// we have the user data for the rest of the page
echo "ID: $userData['id']";
echo "Username: $userData['username']";

只是一个例子,我的代码可能有缺陷。但我希望你能明白。在我的示例中,我只在会话中存储用户的id。然后我的函数(在我的代码中的其他任何东西之前使用)将用户信息返回到一个数组中。然后你可以在页面的任何地方使用$userData数组

尝试使用反向。

if(isset($_SESSION['member_name']) && isset($_SESSION['member_id'])) {
//your content
}
else
header("Location: /LESSON5/1%20-%20LOGIN.php");

最新更新