即使在访问它们之前启动会话,会话变量也会丢失

时间:2016-09-04 19:55:19

标签: php session cookies

对于标题感到抱歉,写一个好标题总是很难。

我使用函数启动会话,因此我可以声明/配置所有内容。

public static function sec_session_start() {
    if (ini_set('session.use_only_cookies', 1) === FALSE) {
        $session_error = 'Error: Cannot create new user session.';
        return $session_error;
    }
    else {
        $session_name   = 'aet_session_id';
        $domain         = '.domain.com';
        $secure         = TRUE;
        $httpOnly       = TRUE;                         // prevents cookie theft

        // Get the current cookies params.
        $cookieParams = session_get_cookie_params();
        // Set the current cookies params.
        session_set_cookie_params($cookieParams['lifetime'], $cookieParams['path'], $domain, $secure, $httpOnly);

        // Sets the session name to the one set above.
        session_name($session_name);
        session_start();                                // Start the PHP session

        if (!isset($_SESSION['CREATED'])) {
            $_SESSION['CREATED'] = time();
        } else if ((time() - $_SESSION['CREATED']) > 1800) {
            // session started more than 30 minutes ago
            session_regenerate_id(TRUE);                // change session ID for the current session and invalidate old session ID
            $_SESSION['CREATED'] = time();              // update creation time
        }
/*
        $hasExpired = FALSE;

        if (isset($_SESSION['staff_id'], $_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY']) > 9999) {  // 300 (5 mins)
            // last request was more than 5 minutes ago
            $_SESSION = array();                        // unset $_SESSION variable for the run-time
            $params = session_get_cookie_params();      // Get session parameters
            setcookie(session_name(),                   // Delete the actual cookie
                      '',
                      time() - 3600,
                      $params["path"],
                      $params["domain"],
                      $params["secure"],
                      $params["httponly"]);
            session_destroy();                          // destroy session data in storage

            $hasExpired = TRUE;                         // now we know the user has lost his session for inactivity
        }

        $_SESSION['LAST_ACTIVITY'] = time();            // update last activity time stamp*/
    }

    //return $hasExpired;
}

此函数属于在每个域/子域的每个index.php中初始化的类。

如果我指定子域名:

$domain = 'sub.domain.com';

对于cookie(session_set_cookie_params()),那么会话变量适用于该子域,但我需要为另一个子域使用相同的会话,所以我删除了子域名,在域名前留下了一个前导点:

可选注释*(当我开始为另一个需要在主域和多个子域中进行会话的网站开始编写此框架时,这工作正在开始,但是目前,在这个项目中我只需要一个会话subdomain但现在我需要更改它。值得一提的是,这是在另一个主机中使用较低的PHP版本和另一个配置。)

出于一些神秘的原因,现在会话变量在重新加载时会丢失(在这种情况下,在检查登录详细信息后执行header('Location: /');时)。

知道为什么会这样吗?我无法弄清楚发生了什么...

我做了一些调试:我尝试在重定向之前回显会话变量(帐户id和login_string)并且它们没问题,但是在重定向之后我无法回显它们。

// index.php
$web_user = new web_user();
$web_user->sec_session_start();

echo $_SESSION['client_id'];

$client = $web_user->login_check();

// since $client is FALSE
include('login_post.php');

// login_post.php
$web_user->client_login($email, $password);

// web_user.php
$client = new Client();
// login is ok
$_SESSION['client_id'] = $client->getId();
return 'login_ok';

// back in login_post.php
header('Location: /');

// index.php
$web_user = new web_user();
$web_user->sec_session_start();

echo $_SESSION['client_id'];

输出:登录前后的“未定义索引:client_id”(重定向)。

因此...

$client = $web_user->login_check();

再次FALSE ......

澄清一点......我说另一个子域名因为我需要会话对域和所有子域都有效。但问题在于同一个子域:

让我们说login.domain.com,如果我在cookie中指定子域(登录),会话变量可以工作(允许我登录)但是如果我删除子域(留下前导点)那么他们就赢了再工作了(我将无法登录)。

如果我没错:

login.domain.com

会话仅对该子域有效,但是:

.domain.com

会话将对域和所有子域(包括login.domain.com)有效,对吧?

1 个答案:

答案 0 :(得分:0)

问题解决了。对于cookie域中的前导点,不再需要了。感谢https://stackoverflow.com/a/23086139/4067132

我和.subdomain.domain.com上有旧cookie,因此请求不匹配。

删除旧Cookie并将Cookie域更改为:

DATE

会话变量再次起作用。此外,现在我的网站只需要一个cookie用于所有子域名。