错误使用PHP会话(两个登录屏幕)


Bug using PHP Sessions (Two Log On screens)

在我正在开发的应用程序中,我有一个bug,我将浏览器指向我的应用程序的index.php,然后正确地重定向到login.php,如果没有当前会话。我的问题是,在我在login.php上输入正确的详细信息并单击提交后,我被链接到另一个login.php屏幕(而不是返回到具有活动会话的index.php),并要求再次输入我的详细信息。第一个屏幕具有与index.php相同的CSS格式,而第二个屏幕没有。

在第二个屏幕上输入我的详细信息并点击登录后,会话似乎正常运行。而且,很多时候,我将看到一个登录屏幕,我将登录并显示用户正确的主屏幕数据(这需要对登录数据进行成功查询),但是如果我从index.php导航到另一个需要活动会话的屏幕,它将显示未格式化的login.php屏幕。

如果我登出,导航到另一个不受限制的页面,并试图在同一浏览器会话中再次登录,登录功能只有一个屏幕。

以下是相关文件的片段:

    index.php
    <?php
    include_once 'db_functions.php';
    require_once 'access.php';
    if (isset($_POST['action'])) {
        if (userIsLoggedIn()) {
            header('Location: http://www.myapp.com/index.php');         //prevents users from having to confirm form resubmission if they refresh the page
        }
    }
    if (!userIsLoggedIn()) {
        include 'login.php';
        exit();
    }

login:

login.php
<body>
<h1>Log In</h1>
<?php
    if (isset($loginError)) {
          echo $loginError; 
    }
?>
    <form action="" method="post">
    <div>
    <label for="email">Email: <input type="text" name="email" id="email" /> </label>
    </div>
    <div>
    <label for="password">Password: <input type="password" name="password" id="password" /></label>
    </div>
    <div>
    <input type="hidden" name="action" value="login" />
    <input type="submit" value="Log in"  />
    </div>
    </form>
</body>

access.php:

 <?php
 function userIsLoggedIn() {
    if (isset($_POST['action']) and $_POST['action'] == 'login') {
        if (!isset($_POST['action']) or $_POST['email'] == '' or
        !isset($_POST['password']) or $_POST['password'] == '') {
            $GLOBALS['loginError'] = 'Please fill in both fields';
            return FALSE;
        }
    $email = $_POST['email'];
    $password = $_POST['password'];
    if (databaseContainsAuthor($email, $password)) {
        session_start();  //LINE 17
        $_SESSION['loggedIn'] = TRUE;
        $_SESSION['email'] = $email;
        $_SESSION['password'] = $password;
        return TRUE;
    }
    else {
        session_start();
        unset($_SESSION['loggedIn']);
        unset($_SESSION['email']);
        unset($_SESSION['password']);
        $GLOBALS['loginError'] = 'The specified email address or password was incorrect.';
        return FALSE;
    }
    }
    if (isset($_POST['action']) and $_POST['action'] == 'logout') {
        session_start();
        unset($_SESSION['loggedIn']);
        unset($_SESSION['email']);
        unset($_SESSION['password']);
        header('Location: ' . $_POST['goto']);
        exit();
    }
    session_start();
    if (isset($_SESSION['loggedIn'])) {
        return databaseContainsAuthor($_SESSION['email'], $_SESSION['password']);
    }
}
function databaseContainsAuthor($email, $password) {
    include_once './db_functions.php';
    $db = new DB_Functions();
    $result = $db->accountExists($email, $password);
    return $result;
}
?>

任何帮助都将非常感激!

:错误日志显示此错误多次出现:

PHP Notice:  A session had already been started - ignoring session_start() in /home3/monitot5/public_html/app/access.php on line 17

Access.php第17行:

if (databaseContainsAuthor($email, $password)) {
    session_start();  //LINE 17
    $_SESSION['loggedIn'] = TRUE;

你应该做的是使用

session_start();

access.php文件的开头,不要再使用这个函数。

您还应该完全更改access.php文件的登录名。在这个文件中,您应该做的第一件事就是检查这个用户是否有一个有效的会话。现在你检查它在文件的末尾,可能更早,你清除它,因为你不设置会话,如果没有$_POST数据。

另外,你不应该在会话中使用password。这是非常不安全的。当用户填写有效的用户名/电子邮件和密码时,您应该简单地为您的系统存储登录信息,如果用户已注销,则取消设置。

对不起,我不会为你写完整的代码。您应该简单地查看Google中的一些代码示例,以检查如何在PHP中处理用户登录/注销。