php + passing session between subdomains (http and https)

ims1010
ims1010 used Ask the Experts™
on
I'm trying to pass my session ID across 2 subdomains.  The domains are as follows:

1) http://www.mydomain.com
2) https://secure.mydomain.com

I have added the following line to my .htaccess file:
php_value session.cookie_domain .mydomain.com

The strange thing is that if I use:
3) http://mydomain.com

The sessionid for"mydomain.com"  is the same as "secure.mydomain.com".  It seems only the "www" version is different.

I've attached my sample testing code below.

Thanks in advance for your help - this is driving me crazy :-)

Cheers
Ivan


<?php
 
function GetCartId()
{	
       if(isset($_COOKIE["CartID"]))
	{					
		return $_COOKIE["CartID"];
	}
	else
	{
		// There is no cookie set. We will set the cookie
		// and return the value of the users session ID				
               session_set_cookie_params('', '/', '.mydomain.com', 0);
               session_start();
		setcookie("CartID", session_id());	
		
		return session_id();
	}
}
 
$CookieID = GetCartId();	
 echo "AnnasCartID: $CookieID<br>";	
 
?>

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
ssl certs are linked to unique IP addresses. I doubt sessions can traverse multiple IP addresses. I would assume your secure domain has a different IP address to the www...

Author

Commented:
Hi there,

Thanks for your response!

The IP address of both the SSL cert and the "www" address are both the same.

Cheers
Ivan

Commented:
Then how about the 'secure' domain, same ip as www?
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Commented:
the point is, you're trying to get a session to be valid across multiple protocols (http & https), subdomains and IP addresses. Aint going to happen.

Author

Commented:
Yes - the ip of "secure.mydomain.com" is the same as "www.mydomain.com"
Most Valuable Expert 2011
Top Expert 2016

Commented:
Sessions use cookies to identify what subdomains they are attached to.  Cookies, in turn, can be sent by the browser for either HTTPS or both HTTP and HTTPS.  Please see the code snippet and look over the comments, especially those at lines 35 - 55.  You might want to install and test this.  Let me know if you have any questions.  Best, ~Ray
<?php // RAY_cookie_example.php
 
// RECEIVE FORM INPUT AND SET A COOKIE WITH THE NAME AND VALUES FROM THE FORM
// MAN PAGE: http://us.php.net/manual/en/function.setcookie.php
// TO SEE COOKIES IN FIREFOX, FOLLOW TOOLS => OPTIONS => PRIVACY => SHOW COOKIES
 
define('COOKIE_LIFE', 60*60*24); // A 24-HOUR DAY IN SECONDS ( = 86,400 )
 
if (!empty($_POST)) // IF THE FORM HAS BEEN POSTED
{
 
// TIDY UP THE POST INPUT - CLEAN AND NOT MORE THAN 16 BYTES
   $name = substr(clean_string($_POST["name"]),0,16);
   $data = substr(clean_string($_POST["data"]),0,16);
 
// BE SURE WE HAVE USEFUL INFORMATION
   if ( ($name == '') || ($data == '') ) die("MISSING INPUT: PLEASE <a href=\"$PHP_SELF\">TRY AGAIN</a>");
 
 
// CHOOSE THE COOKIE NAME AND VALUE
   $cookie_name    = $name;
   $cookie_value   = $data;
 
 
 
// ESTABLISH THE COOKIE LIFE - CHOOSE ONE OF THESE FOR THE COOKIE
// USE THIS TO MAKE COOKIE EXPIRE AT END OF BROWSER LIFE
   $cookie_expires = 0;
 
// USE THIS TO MAKE A PERSISTENT COOKIE - DEFINE COOKIE_LIFE IN SECONDS - date('Z') IS UTC OFFSET IN SECONDS
   $cookie_expires = time() + date('Z') + 30 * 60 * 60 * 24;
 
 
 
// ESTABLISH THE COOKIE DOMAIN SCOPE - CHOOSE ONE OF THESE FOR THE COOKIE
// MAKE THE COOKIE AVAILABLE TO ALL DIRECTORY PATHS IN THE WWW ROOT
   $cookie_path	= '/';
 
// MAKE THE COOKIE AVAILABLE TO ALL SUBDOMAINS - DOMAIN NAME STARTS WITH DOT AND OMITS WWW (OR OTHER SUBDOMAINS).
   $x = explode('.', strtolower($_SERVER["HTTP_HOST"]));
   $y = count($x);
   if ($y == 1) // MAYBE 'localhost'?
   {
      $cookie_domain = $x[0];
   } else // SOMETHING LIKE 'www2.atf70.whitehouse.gov'?
   {
// USE THE LAST TWO POSITIONS TO MAKE THE HOST DOMAIN
      $cookie_domain = '.' . $x[$y-2] . '.' . $x[$y-1];
   }
 
 
 
// MAKE THE COOKIE AVAILABLE TO HTTP, NOT JUST HTTPS
   $cookie_secure    = FALSE;
 
 
 
// HIDE COOKIE FROM JAVASCRIPT (PHP 5.2+)
   $cookie_http      = TRUE;
 
 
 
// SET THE COOKIE
   if (setcookie($cookie_name, $cookie_value, $cookie_expires, $cookie_path, $cookie_domain, $cookie_secure, $cookie_http))
   {
      echo "<br/>SUCCESS!  THE COOKIE HAS BEEN SET AND WILL BE AVAILABLE TO THE NEXT PAGE LOAD \n";
   }
   else
   {
      echo "<br/>FAILURE!  THE COOKIE WAS NOT SET AS EXPECTED \n";
   }
 
 
 
// AT THIS POINT, THE COOKIE HAS BEEN SET, BUT IT IS _NOT_ AVAILABLE TO THIS SCRIPT.
// THE COOKIE WILL NOT BE AVAILABLE TO OUR SERVER UNTIL THE NEXT SCRIPT!
// THIS IS BECAUSE THE BROWSER SENDS THE COOKIE TO OUR SCRIPT BEFORE OUR SCRIPT STARTS RUNNING.
// HOWEVER THE $_COOKIE ARRAY IS NOT IMMUTABLE, AND WE CAN ADD INFORMATION TO IT
// IF WE WANT TO USE IT IN THIS SCRIPT.  THIS IS PROBABLY A BAD PROGRAMMING PRACTICE
   echo '<pre>$_COOKIE CONTAINS '; var_dump($_COOKIE); echo "</pre>\n";
   echo '<pre>$_POST CONTAINS ';   var_dump($_POST);   echo "</pre>\n";
   echo "<br/>THE COOKIE HAS BEEN SET WITH THESE VALUES: \n";
   echo "<br/>COOKIE NAME: $cookie_name \n";
   echo "<br/>COOKIE VALUE: $cookie_value \n";
   echo "<br/>COOKIE EXPIRES: $cookie_expires ";
   echo " == " . date('r') . "\n";
   echo "<br/>COOKIE PATH: $cookie_path \n";
   echo "<br/>COOKIE DOMAIN: $cookie_domain \n";
   echo "<br/>COOKIE SECURE: "; var_dump($cookie_secure); echo " \n";
   echo "<br/>COOKIE HTTP: ";   var_dump($cookie_http);   echo " \n";
 
   echo "<br/>";
   echo "<br/>TO SEE THE COOKIES, IF ANY, <a href=\"{$_SERVER['PHP_SELF']}\">CLICK HERE</a> \n";
   echo "<br/>";
}
 
// END OF SETTING THE COOKIE
?>
 
 
<form method="post">
COOKIE NAME: <input name="name" /><br/>
COOKIE DATA: <input name="data" /><br/>
<input type="submit" />
</form>
 
 
<?php
// SHOW THE COOKIE ARRAY, IF ANY
echo '<pre>$_COOKIE CONTAINS '; var_dump($_COOKIE); echo "</pre>\n";
 
 
 
// A FUNCTION TO FORCE A STRING TO CHARACTERS ONLY
function clean_string($string)
{
   return trim(ereg_replace('[^a-zA-Z0-9_]', '', $string));
}
?>

Open in new window

Most Valuable Expert 2011
Top Expert 2016
Commented:
Here is another example that may help provide a piece of the puzzle.  Note how the session cookie is set near lines 38 - 45.
<?php // RAY_session_cookie_domain.php
/* *
 * QUESTION: WHEN CLIENTS VISIT MY SITE SOMETIMES THEY USE www.mysite.org
 * BUT SOMETIMES THEY USE mysite.org WITHOUT THE WWW.  HOW CAN I HANDLE
 * THE SESSION ISSUES THAT ARISE FROM THIS?
 *
 * ANSWER: ONE WAY IS TO REWRITE THE URL TO REMOVE THE SUBDOMAIN IF IT
 * IS WWW.  FOR EXAMPLE:
 *
 *     Options +FollowSymlinks
 *     RewriteEngine on
 *     RewriteCond %{http_host} ^www\.corz\.org [NC]
 *     RewriteRule ^(.*)$ http://corz.org/$1 [R=301,NC]
 *
 * ANOTHER WAY IS TO MODIFY THE SESSION COOKIE SO IT WORKS ACROSS ALL OF
 * YOUR SUBDOMAINS.  YOUR CHOICE WILL LARGELY DEPEND ON THE WAY YOU WANT
 * TO HANDLE OTHER SUBDOMAINS (OTHER THAN WWW).
 */
 
// DEMONSTRATE HOW TO START SESSIONS THAT WORK IN DIFFERENT SUBDOMAINS PHP 5.2+
error_reporting(E_ALL);
 
 
// MAKE THE SESSION COOKIE AVAILABLE TO ALL SUBDOMAINS
// MAKE A DOMAIN NAME THAT OMITS WWW OR OTHER SUBDOMAINS
// BREAK THE HOST NAME APART AT THE DOTS
$x = explode('.', strtolower($_SERVER["HTTP_HOST"]));
$y = count($x);
if ($y == 1) // POSSIBLY 'localhost'
{
    $host = $x[0];
} else // SOMETHING LIKE 'www2.atf70.whitehouse.gov'?
{
// USE A DOT PLUS THE LAST TWO POSITIONS TO MAKE THE HOST DOMAIN NAME
    $host = '.' . $x[$y-2] . '.' . $x[$y-1];
}
 
// START THE SESSION AND SET THE COOKIE FOR ALL SUBDOMAINS
$sess_name = session_name();
if (session_start())
{
// MAN PAGE http://us.php.net/manual/en/function.setcookie.php
    setcookie($sess_name, session_id(), NULL, '/', $host, FALSE, TRUE);
}
 
 
// PROVE THAT THE COOKIE WORKS IN MULTIPLE DOMAINS
// LOAD UP SOME INFORMATION TO SHOW SESSION CONTENTS
$_SESSION["cheese"] = "Cheddar";
if (!isset($_SESSION["count"])) $_SESSION["count"] = 0;
$_SESSION["count"] ++;
 
 
// PUT UP TWO LINKS WITH DIFFERENT SUBDOMAINS
$gost = ltrim($host,'.'); // STRIP OFF THE DOT THAT WAS NEEDED FOR SETCOOKIE
$dmn_link = 'http://'    . $gost . '/RAY_dump_session.php'; // var_dump() SCRIPT
$www_link = 'http://www' . $host . '/RAY_dump_session.php';
 
echo "<br/><a target=\"_blank\" href=\"$www_link\">$www_link</a>\n";
echo "<br/><a target=\"_blank\" href=\"$dmn_link\">$dmn_link</a>\n";
 
 
// SHOW WHAT IS IN COOKIE AND IN $_SESSION
echo "<pre>";
echo "COOKIE ";
var_dump($_COOKIE);
echo "\n\n";
echo "SESSION ";
var_dump($_SESSION);
echo "</pre>\n";
 
 
?>
<form method="post">
<input type="submit" value="CLICK ME" />
</form>

Open in new window

Author

Commented:
Hi Ray -
Thanks for unlocking the puzzle!  Rewriting the URL worked for me.

Cheers!
Ivan
Most Valuable Expert 2011
Top Expert 2016

Commented:
Thanks for the points - it's a great question!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial