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