Solved

Multi-Domain Cookies Login PHP

Posted on 2012-03-24
8
543 Views
Last Modified: 2012-03-26
Ok,

So I have a network of sites all linking to same members area, therefore Id like to handle login for all sites when user logs in on just 1 of the domains.

So lets say user logs in into a.com, I want to login him to also www.a.com and b.com and c.com and www. for each.

All domains are pointing to same directory on server.
Any ideas how could I achieve cookies generation/destroyal for multi-domain site?
0
Comment
Question by:GVNPublic123
  • 5
  • 3
8 Comments
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 500 total points
ID: 37761198
Cookies apply to only one domain.  A cookie from a.com will not be returned to b.com and a setcookie issued on a.com will not affect a cookie from b.com.

This would seem to be an impediment.  However the login script on any of these sites can redirect to the "set logged in" script on the other sites.  The redirection is a GET method request and it can include some security measures if you sense a need for that.  Here is the general design pattern used by organizations like doubleclick that send information from domain to domain when a client clicks on an advertisement.  Your design can follow this sequence.  Sorry I do not have a demonstration script that shows this in action, but I believe the principles go something like this...

1. When any of the sites gets a successful login it sets a cookie for its own login status, then starts a cascade of "set_logged_in" calls to the complete list of sites.
2. You have a list of "set_logged_in" URLs  saved in some common place that all the sites can access.  This list defines the cascade.  Any of the sites can start the cascade.
3. Each site accesses the cascade list.  This list is treated as a ring, with each site setting the logged-in status cookie for its own domain and then transferring control to the next domain in the list.  At the bottom of the list, the logic goes back to the top of the list (making the ring).
4. When the first site receives the call for the set_logged_in, it recognizes its own signal string and stops the cascade.  The client is thus logged in to all the sites and sees the page from the site that initiated the login.

It does not matter if the sites are on the same server, so long as they share a common cascade list.  You can read this list from a canonical source with file_get_contents() or you can hardcode this list in a script that is stored in all of the servers.  It just needs to be consistent from domain to domain.

Logout is trickier, since there is no such thing as a certain logout. The cookies for all the sites will persist as long as the cookie life.  If the cookie life is zero, that means that the cookies will disappear when the client closes the last instance of the browser.  This means that if multiple windows or tabs are open, the client must close all of them to remove the cookie.  But if the cookie life is persistent to a specified date/time, the cookies will be returned (and the client will appear to be logged in) until that date/time is passed.  If the client just closes the browser without going through the logout process (a process that would initiate another cascade of redirects) the login status of each site will be determined by the way that particular site set the cookie.

Of course, if the client logs out via a script, the script can initiate a cascade of logouts, setting cookies to expired status, and the client logout will be complete.  You cannot depend on the client doing this.

Each header("Location") in the cascade of redirects is a GET method request.  You can pass information in the URLs.  This implies that you might want to encode the information in a way that keeps it secret from prying eyes.  You might also want to timestamp the information to keep a client from stealing the GET arguments and reusing them.  Encryption/Decryption using a common key would be one of the ways to pass GET arguments between domains.

HTH, ~Ray

To set cookies that work across more than just a.com (for example, cookies that will work on a.com, www.a.com, test.a.com, etc., you can follow a pattern like this one.
<?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\.example\.org [NC]
 *     RewriteRule ^(.*)$ http://example.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);
// POSSIBLY 'localhost'
if ($y == 1)
{
    $host = $x[0];
}
// MAYBE SOMETHING LIKE 'www2.atf70.whitehouse.gov'
else
{
    // 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
// STRIP OFF THE DOT THAT WAS NEEDED FOR SETCOOKIE
$gost = ltrim($host,'.');
$dmn_link = 'http://'    . $gost . '/RAY_dump_session.php'; // var_dump() SCRIPT
$www_link = 'http://www' . $host . '/RAY_dump_session.php';

echo "<br/>Click these links to get a new window and see the _SESSION and _COOKIE arrays" . PHP_EOL;
echo "<br/><a target=\"_blank\" href=\"$www_link\">$www_link</a>" . PHP_EOL;
echo "<br/><a target=\"_blank\" href=\"$dmn_link\">$dmn_link</a>" . PHP_EOL;


// SHOW WHAT IS IN COOKIE AND IN $_SESSION
echo "<pre>";
echo "COOKIE ";
var_dump($_COOKIE);
echo PHP_EOL . PHP_EOL;
echo "SESSION ";
var_dump($_SESSION);
echo "</pre>";


?>
<form method="post">
<input type="submit" value="CLICK ME" />
</form>

Open in new window

HTH, ~Ray
0
 

Author Comment

by:GVNPublic123
ID: 37762576
Yeh, I don't wanna go with mod_rewrite so Ill set cookies for subdomain too.
Can I just do:
setcookie($sess_name, session_id(), NULL, '/', 'www.a.com', FALSE, TRUE);
If this setcookie is called from a.com (without www). Will it be accepted?
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37762605
Where you have www.a.com in the setcookie() function call, you probably do not want that.  Instead you want .a.com as shown in the code snippet above.  Follow the variable named $host for an example of what works with multiple subdomains with setcookie().
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37762615
Sidebar note.  You might not want to use the session to handle this.  My thinking is not 100% clear about what you are trying to do.  It might be easier to set up your tests if you used a cookie that was not a session cookie.  During the period of testing you can store meaningful information in the cookie to form a signal string that is easy to see with Firefox.  Even with the scripts on the same server, the PHP session handler might not want to let you share session data across domains.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:GVNPublic123
ID: 37762786
When I do .a.com it gets messy. When I set cookies for .a.com login works, but logout doesnt. I logout by setcookie($name, null, time()-1000, '', '.a.com') login same just time is positive and value not null.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37762804
I think your logout setcookie statement should look something like this:
setcookie($name, NULL, time()-42000, '/');

Open in new window

The essential element here is the cookie name and the fact that the expiry is in the past.
0
 

Author Comment

by:GVNPublic123
ID: 37762818
Yep but it doesnt work. If I set cookie as .a.com it wont unset it that way. Dunno why...
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37762838
It works for me.  Here is a login / logout sequence that shows the moving parts.
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_2391.html

In semi-related news, I am working on an article about the multi-site login right now.  Hope to post it later today.
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Join & Write a Comment

These days socially coordinated efforts have turned into a critical requirement for enterprises.
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now