会话和子域

时间:2011-03-09 10:35:09

标签: php session subdomain session-cookies

我一直试图让我的会话在我的子域中运行,我很确定我在周一工作但是在星期二添加一些代码后它周三没有工作!我使用了代码ini_set("session.cookie_domain", $domain); $domain = .example.com

我网站的主页目前位于test.example.com上,我通过test.example.com/login访问登录页面。当我输入此地址时,地址栏中的网址会自动更改为http://www.test.example.com/login,这就是问题所在。会话是为www.test.example.com创建的,但网站上的大多数链接都指向test.example.com/<sub folder>

我能想到的唯一可能就是把它扔掉是我处理会话的方式。在每个页面中都会启动一个会话。首先设置ini_set("session.cookie_domain", $domain);,然后启动会话。接下来我检查会话是否已过期。如果会话已过期,则会销毁当前会话并取消设置,然后会创建新会话。其余的只是设置用户信息。

我最近添加的唯一内容是会话到期检查。我试过绕过它,但它没有改变任何东西。

非常感谢任何帮助。我可以发布代码,如果它更容易。

迈克

3 个答案:

答案 0 :(得分:1)

请添加一些代码:)。

我只能告诉你我们是如何实现相同的功能的。尝试添加

<directory "/path/to/your/docroot">
    php_value session.cookie_domain ".example.com"
</directory>

到您的虚拟主机配置。这是我们为使这项功能发挥作用而必须做的唯一事情。现在,我们可以使用相同的cookie访问所有子域,而无需添加所有额外的代码。我不是说这是一个解决方案,但这种方法使测试变得不那么复杂。

修改

您可以在网络服务器的配置中设置虚拟主机。假设您使用apache,它们将位于httpd.conf中,或者存在于httpd.conf中包含的文件系统上的其他文件中。 httpd.conf位于您的系统上取决于您的配置,但如果您使用Linux,它可能位于/ etc / apache,/ etc / httpd,/ usr / local / apache,/ usr / local / httpd

找到此文件后,它将包含一个或多个这样的条目:

<VirtualHost *:80>
    ServerAdmin webmaster@yourdomain.org
    DocumentRoot /var/www/yourdomain/www
    ServerName yourdomain.org
    <directory "/var/www/yourdomain/www">
                Options FollowSymLinks Includes
                AllowOverride All
                Order allow,deny
                Allow from all
        </directory>
</VirtualHost>

修改它看起来像这样的代码:

<VirtualHost *:80>
    ServerAdmin webmaster@yourdomain.org
    DocumentRoot /var/www/yourdomain/www
    ServerName yourdomain.org
    <directory "/var/www/yourdomain/www">
                Options FollowSymLinks Includes
                AllowOverride All
                Order allow,deny
                Allow from all
                php_value session.cookie_domain ".yourdomain.org"
        </directory>
</VirtualHost>

注意php_value session.cookie_domain ".yourdomain.org"行。

将此行添加到此域的所有服务器配置中,您的Cookie将被共享。

答案 1 :(得分:0)

如果不了解更多细节,则无法进行调试。

您可能需要首先检查Cookie是否正确设置,以及它们是否实际返回到服务器。

使用一个工具,可以让您在浏览器上看到标题(webdeveloper工具栏/ liveheaders / firebug for Firefox),看看服务器是否实际上要求浏览器接受cookie - 以及用于什么。

答案 2 :(得分:0)

请原谅我不知道'虚拟主机配置'是什么。我的代码运行如下:

主页面将包含session.php

function Session() 
{
    $this->time = time();
    $this->startSession();
}

function startSession()
{
    global $serverFunctions;

    $serverFunctions->setSubdomainSharing();

    session_start();

    $this->checkSessionLife();

    //check if user is logged in
    $this->logged_in = $this->checkLogin();

    //if user is not logged in then it is given guest credintials
    if (!$this->logged_in)
    {
        $this->user_name = $_SESSION['user_name'] = GUEST_NAME;
        $this->user_level = $_SESSION['user_level'] = GUEST_LEVEL;
    }
    if (!isset($_SESSION['language']))
    {
        $this->setLanguage("translation_english");
    }
    else
    {
        $this->user_language = $_SESSION['language'];
    }
}

function checkSessionLife()
{
    global $serverFunctions;

    if (isset($_SESSION['start_time']))
    {
        $session_life = time() - $_SESSION['start_time'];

        if ($session_life > 15)
        {
            $this->logout();
            $serverFunctions->setSubdomainSharing();
            session_start();
        }
    }
    else if (!isset($_SESSION['start_time']))
    {
        //logout any session that was created 
        //before expiry was implemented
        $this->logout();
        $serverFunctions->setSubdomainSharing();
        session_start();
    }

    $_SESSION['start_time'] = time();
}

function logout()
{
    global $database;

    // Unset session variables
    session_destroy();
    session_unset();
    //session_regenerate_id(true);


    $this->logged_in = false;

    // Set user level to guest
    $this->user_name = GUEST_NAME;
    $this->user_level = GUEST_LEVEL;
}

会话文件包含另一个名为serverFunctions的PHP文件。这只是一个允许我格式化URL等的类。

function getAddressPrefix()
{
    $address_prefix = "";

    if ($_SERVER['SERVER_ADDR'] == '127.0.0.1')
    {
        $address_prefix = "http://localhost/myproject";
    }
    else
    {
        $address_prefix = $this->getServerName();
    }

    return $address_prefix;
}

function getServerName()
{
    return "http://" . str_replace("www.", "", $_SERVER['SERVER_NAME']);
}

function formatRequestingPage()
{
    return $this->getServerName() . $_SERVER['SCRIPT_NAME'];
}

function setSubdomainSharing()
{

    if ($_SERVER['SERVER_ADDR'] != '127.0.0.1')
    {
        $domain = $this->getServerName();

        do
        {
            $domain = substr($domain, strpos($domain, ".", 0) + 1);
        }
        while (substr_count($domain, ".") > 1);
        $domain = ".".$domain;

        ini_set("session.cookie_domain", $domain);
    }
}

当用户登录时,登录请求由process_request.php

处理
function LoginReq()
{
    global $session;
    global $variables;
    global $serverFunctions;

    $retval = $session->login($_POST['user_name'], $_POST['password']);

    if ($retval)
    {
        header("Location: " . $serverFunctions->getAddressPrefix());
        exit();
    }
    else
    {
        $_SESSION['variables_array'] = $_POST;
        $_SESSION['error_array'] = $variables->getErrorArray();
        header("Location: " . $serverFunctions->getAddressPrefix() . "/login/");
        exit();
    }
}

如果我遗漏任何东西或者需要解释一下会发生什么,请告诉我。