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

时间:2015-05-26 06:18:35

标签: php session redirect

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

登录页面PHP& HTML

weight x/2

似乎是会话变量<?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> &amp;在登录页面提交时未设置$_SESSION['member_name'] = $member_name,我不知道原因。

此处,如果未设置会话变量(通过!isset),主页应重定向到登录名而不显示主页。在这里,这是行不通的,假设因为上面代码中的会话变量没有设置,并且主页没有正确读取PHP脚本并使主页公开。

HOMEPAGE PHP

$_SESSION['member_id'] = $member_id

我知道<?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"); } ?> 变量中存在错误,但我无法确定差距在哪里。对此的任何意见将不胜感激。

2 个答案:

答案 0 :(得分:1)

您需要使用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()。只使用mysqli并不能保护你。

总而言之,如果您使用像Yii这样的框架,您将省去很多麻烦 - 登录和注册已经开箱即用,密码上有bcrypt,以及数百个使用框架的其他原因:) Yii只是我的首选,但任何框架都可以帮助任何程序员。我很久没有处理会话或登录/注册代码......

<强> ADDED 在表中添加更多值以存储在会话中:

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数组。

答案 1 :(得分:0)

尝试使用反转。

if(isset($_SESSION['member_name']) && isset($_SESSION['member_id'])) {

//your content

}
else
header("Location: /LESSON5/1%20-%20LOGIN.php");