Sessions and subdomains

2019-05-24 07:29发布

问题:

I've been trying to get my sessions running across my subdomains, which I'm pretty sure I got working on Monday but after adding some code Tuesday its not working Wednesday! I've used the code ini_set("session.cookie_domain", $domain); where $domain = .example.com.

My site's main page is currently located on test.example.com and I access the login page through test.example.com/login. When i enter this address, the url in the address bar is automatically changed to http://www.test.example.com/login, and this is where the problem lies. The session is created for www.test.example.com but most links on the site direct to test.example.com/<sub folder>.

The only thing I can think of that might be throwing it off is the way I handle sessions. In every page a session is started. First the ini_set("session.cookie_domain", $domain); is set, then the session is started. Next I check to see if the session has expired. If the session has expired the current session is destroyed and unset then a new session is created. The rest is just setting up user information.

The only thing I've added recently is the session expiry checker. I've tried bypassing it but it hasn't changed anything.

Any help is greatly appreciated. I can post code if it makes it easier.

Mike

回答1:

Please add some code :).

I can only tell you how we achieved the same functionality. Try adding

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

to your virtual host configs. This was the only thing we had to do to make this functionality work. Now we can access all subdomains with the same cookies without adding all the extra code. I don't say this is a solutions, but this approach makes testing a lot less complicated.

Edit

You can set virtual hosts in the configuration of your webserver. Assuming you use apache they will be either in httpd.conf or are present in other files on the filesystem which are included in your httpd.conf. Where httpd.conf is located on your system depends on your configuration, but if you use Linux it will probably be somewhere in /etc/apache, /etc/httpd, /usr/local/apache, /usr/local/httpd

Once you have located this file it will have one or more entries like this:

<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>

And modify the code that it looks like this:

<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>

Notice the php_value session.cookie_domain ".yourdomain.org" line.

Add this line to all server configuration for this domain and your cookies will be shared.



回答2:

This is impossible to debug without knowing more details.

You might want to first check if the cookies are being set properly, and if they are actually being returned to the server.

Use a tool which lets you see headers on your browser (webdeveloper toolbar / liveheaders / firebug for Firefox) and see if the server is actually requesting that the browser accept a cookie - and for what.



回答3:

Forgive me for not knowing but what 'virtual host configs' is. My code runs something like this:

The main page will include 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;
}

The session file includes another PHP file called serverFunctions. This is just a class that allows me to format URL and such.

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);
    }
}

When the user logs in, the login request is handled by 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();
    }
}

If I'm missing anything or need to explain what happens a bit more let me know.