What is the best method to share session across multiple domains on same machime. ie, domain name different like abc.com, xyz.com but single application.

Recommended Answers

All 11 Replies

To have a session on multiple domains you would need to have the session id in the url instead of the sessions cookie as cookies only work for one domain. So when linking to a page, link to a page like this:

<?
echo '<a href="page.php?'.SID.'">Link Title</a>';
?>

The SID is needed (session id) and needs to not be in a string but instead be as the way you would echo an array.

While you can't directly set a cookie for a remote site with php, at least not from what I could tell with some quick tests. You can emulate it by calling a script on a foreign site and passing some values to it in the url.

For example.

<?php
//Site1.com/session.php
session_start(); //This line should have created a cookie called PHPSESSID

//We pass the value of that via a GET request to site2 via an image.
//This is just to illustrate the request. The same thing could be done with cURL or a number of other methods.
echo '<img src="http://www.site2.com/setSession.php?w=PHPSESSID&x='.$_COOKIE['PHPSESSID'].'" />';

//Show a link to the page we just called in the image.
echo '<a href="http://www.site2.com/setSession.php">Site 2</a>';
<?php
//site2.com/setSession.php
session_start();
if( !empty($_GET) )
{
     setcookie($_GET['w'], $_GET['x'])
}
else
{
     print_r($_COOKIE);
     print_r($_SESSION);

     //This *SHOULD* now match the session id from the last site.
     echo session_id();
}

I tried numerous attempts with changing the domain and format for the domain string in setcookie() from my localhost trying to set the cookie for one of my domain names but couldn't get it to work. I imagine this is a cross site scripting security measure, but i'm not sure.

This method suffers from a big drawback though, unless both sites SHARE the SAME session store then you still wont be able to access the data.

Personally I like to override the default session handlers and generally use a database to store my sessions and values etc.
But if both sites reside on the same server, and can share access to a certain directory i'm sure you could configure it that way as well.

This is just another way to ultimately achieve the same effect as above except it doesnt get passed in the actual url, it gets passed kind of behind the scenes.

Thanks...
Passing session id along with URL will work but I prefer cookies. Also I need clean search engine friendly URLs. I have done by making unique session_id for each user but would be same across domains. This is working but I think it makes easy to hack session. So actually I want a more secure solution for this. One another solution is making a master domain and other vanity domains. This need more redirections. so it will take more time compared to my first solution. So can you help me to find simple, fast and secure solution?

It is NOT possible to set a cookie for a different domain then the one that script is currently executing on via php. The closest you can get is specifying .domain.com in the setcookie function and this ONLY pertains to subdomains so that www.domain.com & test.domain.com all have access to the cookie.

Sites that manage multiple domain cookies do it either with redirects, or GET/POST requests which is perfectly legit. This is the simple idea I indicated above.

None the less, if you're using PHP Sessions, then a session is stored as a little text file on the server somewhere depending on your configuration. If the domains are one different physical machines or if they use different locations for storing sessions you will never make it work.

The call to the image was just a quick and dirty was of making a GET request to a different website that passed it the current session ID from the first site and set it up on the second site.

It is a single application and all domains use same session store but domain names are different. ie I am running over 200 sites using same machine and same application and most of the resources are common. I have done it already with cookie. My cookie have a common name CAKEPHP_COOKIE. I know it is possible but I need a BEST solution

so let me try to wrap my head around this, you have 200+ domains we'll call them domain1.com, domain2.com etc etc etc

they all point to the same theoretical directory, aka they are domain aliases.
domain1.com -> /home/user/public_html/
domain2.com -> /home/user/public_html/
domain3.com -> /home/user/public_html/
etc

and when i visit domain1.com you are currently setting 200+ cookies for all of your other domains, with the CAKEPHP_COOKIE value, but setting them for domain2.com, domain3.com etc etc etc?

If you are using 200+ domains then your best option may not be sessions. You may be better an a code invention I made 'cross-side cookies' or otherwise known as 'longer lasting server side cookies'. It works very simular to a session except an extra feature that makes it last longer and uses mysql to store the data. If you are interested the script is as follows:

To create the initial database use the following:

<?
$dbhost='localhost'; //database host (usually localhost)
$accountname='root'; //database username.
$password=''; //database password
$database='my_database'; //database name - not table
 
//configure the above variables.
 
 
$linkID = @mysql_connect($dbhost,$accountname,$password)
	or die("Could not connect to MySQL server");
@mysql_select_db($database) or die("Could not select database");

mysql_query('CREATE TABLE `'.$database.'`.`cookies` (`name` TEXT NOT NULL, `value` TEXT NOT NULL, 
`ip` TEXT NOT NULL, `expires` TEXT NOT NULL) ENGINE = MyISAM') or die(mysql_error());
echo "Table named 'cookies' has been created successfully."
?>

Make at the top of all your files or use include() to import the following script into your pages:

<?
$dbhost='localhost';
$accountname='root';
$password='';
$database='my_database';

$linkID = @mysql_connect($dbhost,$accountname,$password)
	or die("Could not connect to MySQL server");
@mysql_select_db($database) or die("Could not select database");

function ssl_cookie_make($cookies_minutes_till_expire,$cookies_houres_till_expire,$cookies_days_till_expire,$cookiename,$cookievalue)
    {
    $cookiename=str_replace("'",'"',$cookiename);
    $cookies_months_till_expire=0;
    $cookieexpiresy=date(Y);
    $cookieexpiresm=date(m)+$cookies_months_till_expire;
    $cookieexpiresj=date(j)+$cookies_days_till_expire;
    $cookieexpiresg=date(G)+$cookies_houres_till_expire;
    $cookieexpiresi=date(i)+$cookies_minutes_till_expire;
    setcookie('ssl_cookie', gethostbyaddr($_SERVER['REMOTE_ADDR']),  time() + 31536000); 
    if ($cookieexpiresi>59)
        {
        while ($cookieexpiresi>59)
            {
            $cookieexpiresg+=1;
            $cookieexpiresi-=60;
            }
        }
    if ($cookieexpiresg>24)
        {
        while ($cookieexpiresg>24)
            {
            $cookieexpiresj+=1;
            $cookieexpiresg-=24;
            }
        }
    if ($cookieexpiresj>30)
        {
        while ($cookieexpiresj>30)
            {
            $cookieexpiresm+=1;
            $cookieexpiresj-=31;
            }
        }
    if ($cookieexpiresm>12)
        {
        while ($cookieexpiresm>12)
            {
            $cookieexpiresy+=1;
            $cookieexpiresm-=12;
            }
        }
    mysql_query("INSERT INTO `cookies` SET `name`='".$cookiename."', `value`='".$cookievalue."', `ip`='".gethostbyaddr($_SERVER['REMOTE_ADDR'])."', 
`expires`='".$cookieexpiresy.",".$cookieexpiresm.",".$cookieexpiresj.",".$cookieexpiresg.",".$cookieexpiresi."'");
    }


function ssl_cookie_updateip()
    {
    mysql_query("UPDATE `cookies` SET `ip`='".gethostbyaddr($_SERVER['REMOTE_ADDR'])."' WHERE `ip`='".$_COOKIE['ssl_cookie']."'");
    setcookie('ssl_cookie', gethostbyaddr($_SERVER['REMOTE_ADDR']), time() + 31536000); 
    }
 
function ssl_cookie_value($cookiename)
    {
    $cookiename=str_replace("'",'"',$cookiename);
    $cookiesql=mysql_query("SELECT * FROM `cookies`");
    $cookiedateexplode=explode(',',date(Y.','.m.','.j.','.G.','.i));
    while ($cookierow=mysql_fetch_array($cookiesql))
        {
        $cookiesqlexplode=explode(',',$cookierow['expires']);
        if ($cookiesqlexplode[0]<=$cookiedateexplode[0] && $cookiesqlexplode[1]<=$cookiedateexplode[1] && $cookiesqlexplode[2]<=$cookiedateexplode[2] 
        && $cookiesqlexplode[3]<=$cookiedateexplode[3] && $cookiesqlexplode[4]<=$cookiedateexplode[4])
            {
            mysql_query("DELETE FROM `cookies` WHERE `expires`='".$cookierow['expires']."'");
            }
        unset($cookiesqlexplode);
        }
    unset($cookiedateexplode);
        
    
    
    if (isset($_COOKIE['ssl_cookie']))
        {
        $cookieresult=mysql_query("SELECT `value` FROM `cookies` WHERE `ip`='".$_COOKIE['ssl_cookie']."' AND `name`='".$cookiename."'");
        } else {
        $cookieresult=mysql_query("SELECT `value` FROM `cookies` WHERE `ip`='".gethostbyaddr($_SERVER['REMOTE_ADDR'])."' AND `name`='".$cookiename."'");
        }
    $cookierow=mysql_fetch_array($cookieresult);
    return $cookierow['value'];
    }
    
function ssl_cookie_changevalue($cookiename,$cookienewvalue)
    {
    $cookiename=str_replace("'",'"',$cookiename);
    if (isset($_COOKIE['ssl_cookie']))
        {
        mysql_query("UPDATE `cookies` SET `value`='".$cookienewvalue."' WHERE `name`='".$cookiename."' AND `ip`='".$_COOKIE['ssl_cookie']."'");
        } else {
        mysql_query("UPDATE `cookies` SET `value`='".$cookienewvalue."' WHERE `name`='".$cookiename."' AND `ip`='".gethostbyaddr($_SERVER['REMOTE_ADDR'])."'");
        }
    }
    
function ssl_cookie_changeexpire($cookiename,$cookies_minutes_till_expire,$cookies_houres_till_expire,$cookies_days_till_expire)
    {
    $cookiename=str_replace("'",'"',$cookiename);
    $cookies_months_till_expire=0;
    $cookieexpiresy=date(Y);
    $cookieexpiresm=date(m)+$cookies_months_till_expire;
    $cookieexpiresj=date(j)+$cookies_days_till_expire;
    $cookieexpiresg=date(G)+$cookies_houres_till_expire;
    $cookieexpiresi=date(i)+$cookies_minutes_till_expire;
    if ($cookieexpiresi>59)
        {
        while ($cookieexpiresi>59)
            {
            $cookieexpiresg+=1;
            $cookieexpiresi-=60;
            }
        }
    if ($cookieexpiresg>24)
        {
        while ($cookieexpiresg>24)
            {
            $cookieexpiresj+=1;
            $cookieexpiresg-=24;
            }
        }
    if ($cookieexpiresj>30)
        {
        while ($cookieexpiresj>30)
            {
            $cookieexpiresm+=1;
            $cookieexpiresj-=31;
            }
        }
    if ($cookieexpiresm>12)
        {
        while ($cookieexpiresm>12)
            {
            $cookieexpiresy+=1;
            $cookieexpiresm-=12;
            }
        }
    if (isset($_COOKIE['ssl_cookie']))
        {
        mysql_query("UPDATE `cookies` SET `expires`='".$cookieexpiresy.",".$cookieexpiresm.",".$cookieexpiresj.",".$cookieexpiresg.",".$cookieexpiresi."' 
    WHERE `name`='".$cookiename."' AND `ip`='".$_COOKIE['ssl_cookie']."'");
        } else {
        mysql_query("UPDATE `cookies` SET `expires`='".$cookieexpiresy.",".$cookieexpiresm.",".$cookieexpiresj.",".$cookieexpiresg.",".$cookieexpiresi."' 
    WHERE `name`='".$cookiename."' AND `ip`='".gethostbyaddr($_SERVER['REMOTE_ADDR'])."'");
        }
    
    $cookiesql=mysql_query("SELECT * FROM `cookies`");
    $cookiedateexplode=explode(',',date(Y.','.m.','.j.','.G.','.i));
    while ($cookierow=mysql_fetch_array($cookiesql))
        {
        $cookiesqlexplode=explode(',',$cookierow['expires']);
        if ($cookiesqlexplode[0]<=$cookiedateexplode[0] && $cookiesqlexplode[1]<=$cookiedateexplode[1] && $cookiesqlexplode[2]<=$cookiedateexplode[2] 
        && $cookiesqlexplode[3]<=$cookiedateexplode[3] && $cookiesqlexplode[4]<=$cookiedateexplode[4])
            {
            mysql_query("DELETE FROM `cookies` WHERE `expires`='".$cookierow['expires']."'");
            }
        unset($cookiesqlexplode);
        }
    unset($cookiedateexplode);
    }
?>

Also the first 5 lines of the above script will need configuring to your database settings. Then to use the above functions, the following is a brief example:

<?
//update ip address header.
ssl_cookie_updateip();

//This function creates a server-side cookie.
//ssl_cookie_make(mins_expire,  houres_expire,  days_expire,  cookie_name,  cookie_value);
ssl_cookie_make(6,0,0,'cookie name','value');


//Note the above functions must be placed before any browser output.
//==========

//This function changes the cookie value for this particular user.
ssl_cookie_changevalue('cookie name','new value');
 
//This function changes when the cookie expires for this particular user.
//ssl_cookie_changeexpire(cookie_name,mins_expire,  houres_expire,  days_expire);
ssl_cookie_changeexpire('cookie name',0,-9,0);

//This function returns the value of a cookie for this particular user.
ssl_cookie_value('cookie name');

?>

Also you will need to place the following function at the top of all your pages before browser output:

<?
ssl_cookie_updateip();

The above code box is the equivilent to the session_start();
Hope that helps.

No. Whena request come to a domain I will start session using common id. So when user1 request come to dom1.com I will create a session session_id('user1.'common'). and when he do a search he will be redirected to appropriate domain. for axample dom2.com. when it comes to dom2.com use session_start('user1.common'). Then the same session will be shared across whatever the site you visit. In this case dom1.com and dom2.com sharing same session. Does that make sense?

But this is not I want. I just want to know any other new and better solution and suggestion from others. need to get other better solutions. :)

Cross site cookie is possible.

The example using DB looks good but isn't it slow? Also these all sites will get a lot of hits from robots and human.

Cross site cookie is possible.

Well doing cookies for multiple domains use to be possible if you would like to be classified as a hacker but since patches to browsers in recent years it is nolonger possible to hack someones system to accept those multisite cookies. That is what wikipedia has to say. So to solve this you will need some sort of recording system on the server side (other than sessions) to swap the data. The only other option other than hacking into the users system is to a- use 200 cookies for 200 domains or b- use a database to swap data between pages. Which option would you like? From your previous post it sounded like the 200 cookies option.

The example using DB looks good but isn't it slow? Also these all sites will get a lot of hits from robots and human.

Ya posted while I was typing and can't edit previous post.
I have used databases in loops that loop millions of times and it seems that databases are a little slower than sessions or even arrays but when using them in the right fashion they can be faster. And in comparison to text files it seems that text files keep on skipping entries unlike mysql.

So the answer to your question is that it would be best to use the $_GET perameter wherever possible but when neccessary, you can use a database for the occasional server side data storage. Because when you think about it how many high traffic website really use any form of sessions at all. None that I have found because it requires too many recourses. Even regular sessions with high loads of traffic can cause a high cpu.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.