即使我已登录,URL重定向 - PHP /会话


URL Redirected even though I am logged in - PHP / Session

我有一个管理页面(../index2.php( 我想在第一次打开浏览器时以我的主 URL 登录。 您必须使用用户名和密码登录才能查看此页面。 显然,如果我注销并关闭浏览器,然后重新打开,它应该重定向到登录页面。 这是 index2.php 页面首次打开时的顶部代码:

<?php
      require_once ("../includes_kl/initialize.php"); // simply sets up database and other classes including session class
?>
<?php
    if(!$session->is_logged_in()) {
    redirect_to("/cms/login.php");
    }
?>

它将重定向到登录.php页面,但该页面执行以下操作:

require_once ("../../includes_kl/initialize.php");
if ($session->is_logged_in()) {// Skip login page if already logged in.
    redirect_to("index.php");
}

而且因为我现在显然已经登录(不确定这是什么时候发生的(,所以它会转到索引.php。

我确认我的 cookie 在打开浏览器时已设置。 饼干是这样做的:

  private function check_login() {
    if (isset($_COOKIE['user_id']) && (isset($_COOKIE['username']))) {
        $_SESSION['user_id']= $_COOKIE['user_id'];
        $_SESSION['username'] = $_COOKIE['username'];
    }
    if (isset($_SESSION['user_id'])) {
        $this->user_id = $_SESSION['user_id'];
        $this->username = $_SESSION['username'];
        $this->logged_in = true;
    } else {
        unset($this->user_id);
        $this->logged_in = false;
    }
}
My session Constructor:
function __construct() {
      session_start();
      $this->check_login();
}

更新:我添加了此代码来回显变量:

function __construct() {
      session_start();
      $this->check_login();
       if ($this->logged_in) {
        echo "Session User Success: " . $this->username;
        } else {
        echo "Session User Fail";
        }
}

当我第一次打开浏览器时,它会返回"会话用户失败"(我在 index2 中出于测试目的取消了重定向.php所以我可以看到结果(。

更新2:

我已经跟踪了未设置cookie的问题。

这是我设置它们的地方:

public function login($user) {
    global $database;
    if ($user) {
        $this->user_id = $_SESSION['user_id'] = $user->id;
        $this->username = $_SESSION['username'] = $user->username;
        setcookie('user_id', $this->user_id, time() + (60 * 60 * 24 * 14));
        setcookie('username', $this->username, time() + (60 * 60 * 24 * 14));
        $this->logged_in = true;
      }
}

这样做是否正确? 这是用户登录时的一部分。 我已经在Chrome中验证了cookie是否已设置。 然而,在 check_login(( 方法中,它不会在第一个"if"语句中找到它们。 "isset"测试失败。

您需要检查几件事。

您应该检查服务器响应HTTP标头并在那里查找Set-Cookie标头。如果它在那里,那么它不是setcookie功能的问题。您需要检查客户端请求 HTTP 标头并在那里查找 Cookie 标头。

但是,更有可能的是,您的服务器响应中没有 Cookie 标头。它可能由于不同的原因而发生,但最有可能是因为"标头已发送"警告。如果您的配置中有 display_errors = off,那么您只能在日志文件中看到此警告。这意味着,您的服务器在调用登录函数之前已开始传输数据(即HTTP响应体(,并且无法设置任何其他标头。您可以使用标题功能进行检查。为此,您需要将此代码放在 index2.php 的最开头:

header('Start: OK');

而check_login函数中的这段代码:

header('Check-Login: OK');

之后,您需要检查响应中包含哪些标头。

还有一件事。你应该避免这样的结构:

$_SESSION['user_id']= $_COOKIE['user_id'];
$_SESSION['username'] = $_COOKIE['username'];

这是一个真正的安全漏洞。只要我可以在客户端更改cookie,我就可以使用任何用户的凭据登录。

我在另一个问题的帮助下想通了。 它确实与Cookies有关。 我只需要在 setcookie(( 方法中设置路径和域。

setcookie('username', $this->username, time(( + (60 * 60 * 24 * 14(, '/', 'domain.com'(;

我的登录.php(首次设置 cookie 的位置(与浏览器打开的 index2 位于不同的文件夹级别.php该文件夹级别。 因此,cookie针对"domain.com/folder/HERE"级别的文件夹设置(这是我的登录名.php是:domain.com/CMS/login.php(。

另一方面,我正在向未设置 cookie 的域/索引 2 打开浏览器.php其中。 因此,它将您发送到登录.php页面,在该页面可以看到cookie,因此它将通过与它刚刚字段相同的测试并将您重定向到索引.php我没有登录。 所以这就是为什么我的浏览器在索引中打开我.php并登录的原因。