How to delete cookie across a domain ...

Hey all.

I need to delete a cookie for all sub-domains of a base domain.

Example, if my site is www.mysite.com, I have a  cookie being created that is available for xxx.mysite.com, yyy.mysite.com etc.

I need to be able to delete the cookie on xxx.mysite.com and have it deleted from yyy.mysite.com.

I've tried the following but it doesn't appear to work.

document.cookie = 'cookie_name=; domain=.mysite.com; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
WebspeederAsked:
Who is Participating?
 
Dave BaldwinConnect With a Mentor Fixer of ProblemsCommented:
"document.cookie" is javascript, not PHP.  You 'expire' a cookie by setting the exact same cookie with a date that is already past.  Which means that you 'expire' it in exactly the same way as you set it.
0
 
GaryCommented:
You cannot delete a cookie that does not belong to the currently accessed domain. i.e.
www.mysite.com is blocked from doing anything with a cookie set from xxx.mysite.com and vice versa

If you set a cookie from mysite.com (no www) then it is available to all domains.
0
 
Dave BaldwinFixer of ProblemsCommented:
Sorry, that's backwards.  ".mysite.com" is supposed to be available on all subdomains.  http://en.wikipedia.org/wiki/HTTP_cookie#Cookie_attributes
0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

 
GaryCommented:
Talking to me Dave? Yes, a mistake there
If you set a cookie from .mysite.com (no www) then it is available to all subdomains.
0
 
Dave BaldwinFixer of ProblemsCommented:
Just checking.  I only have one site with subdomains and I haven't written anything to check the question.  Maybe later if a definitive answer to the original question isn't posted.
0
 
Ray PaseurCommented:
I don't know the answer if you set the cookie in JavaScript, and I do not recommend setting cookies in JavaScript because they are one of the "smells" of a manipulative site that is trying to get the client browser to do something unwanted.

Here is how to set a cookie in PHP.  To make the cookie go away, follow this same process with an expiration date in the past.

Note that if you're talking about one of those domains like example.co.uk you may need some adjustments in lines 48-60.

<?php // RAY_cookie_example.php
error_reporting(E_ALL);

// RECEIVE FORM INPUT AND SET A COOKIE WITH THE NAME, VALUE AND LIFE FROM THE FORM
// MAN PAGE: http://php.net/manual/en/function.setcookie.php
// TO SEE COOKIES IN FIREFOX, FOLLOW SOMETHING LIKE TOOLS => OPTIONS => PRIVACY => SHOW COOKIES (OR "REMOVE INDIVIDUAL")


// REQUIRED AT PHP 5+
date_default_timezone_set('America/New_York');


// IF THE FORM HAS BEEN POSTED
if (!empty($_POST))
{
    // 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);
    $life = clean_number($_POST["life"]);

    // BE SURE WE HAVE USEFUL INFORMATION
    if ( ($name == '') || ($data == '') ) die("MISSING INPUT: PLEASE <a href=\"{$_SERVER['PHP_SELF']}\">TRY AGAIN</a>");


    // CHOOSE THE COOKIE NAME, VALUE, AND LIFE IN SECONDS
    $cookie_name    = $name;
    $cookie_value   = $data;
    $cookie_life    = $life;


    // CONFIGURE THE COOKIE LIFE
    if ($life == 0)
    {
        // USE THIS TO MAKE COOKIE EXPIRE AT END OF BROWSER LIFE
        $cookie_expires = 0;
    }
    else
    {
        // USE THIS TO MAKE A PERSISTENT COOKIE
        $cookie_expires = time() + $cookie_life;
    }


    // MAKE THE COOKIE AVAILABLE TO ALL DIRECTORY PATHS
    $cookie_path	= DIRECTORY_SEPARATOR;


    // 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 PHP_EOL . "<br/>SUCCESS!  THE COOKIE HAS BEEN SET AND WILL BE AVAILABLE TO THE NEXT PAGE LOAD";
    }
    else
    {
        echo PHP_EOL . "<br/>FAILURE!  THE COOKIE WAS NOT SET AS EXPECTED";
    }


    // AT THIS POINT, THE COOKIE HAS BEEN SET, BUT IT IS NOT AVAILABLE IN THIS SCRIPT
    // THE COOKIE WILL NOT BE RETURNED FROM THE CLIENT TO THE SERVER UNTIL THE NEXT HTTP REQUEST
    // THIS IS BECAUSE THE BROWSER SENDS THE COOKIE TO OUR SCRIPT BEFORE OUR SCRIPT STARTS RUNNING
    echo '<pre>';
    echo PHP_EOL . '$_COOKIE CONTAINS '; var_dump($_COOKIE);
    echo PHP_EOL . '$_POST CONTAINS ';   var_dump($_POST);
    echo PHP_EOL . 'THE COOKIE HAS BEEN SET WITH THESE VALUES: ';
    echo PHP_EOL . 'COOKIE NAME:    ' . $cookie_name;
    echo PHP_EOL . 'COOKIE VALUE:   ' . $cookie_value;
    echo PHP_EOL . 'COOKIE EXPIRES: ' . number_format($cookie_expires) . " == " . date('r', $cookie_expires);
    echo PHP_EOL . 'COOKIE PATH:    ' . $cookie_path;
    echo PHP_EOL . 'COOKIE DOMAIN:  ' . $cookie_domain;
    echo PHP_EOL . 'COOKIE SECURE:  '; var_dump($cookie_secure);
    echo           'COOKIE HTTP:    '; var_dump($cookie_http);
    echo "</pre>";
}


// END OF SETTING THE COOKIE - CREATE THE FORM IN HEREDOC NOTATION
$self = $_SERVER["PHP_SELF"];
$form = <<<FORM
<pre>
<form method="post">
COOKIE NAME: <input name="name" /> STRING
COOKIE DATA: <input name="data" /> STRING
COOKIE LIFE: <input name="life" /> INTEGER SECONDS
<input type="submit" />
<b>TO SEE THE EXISTING COOKIES <a href="$self">CLICK HERE</a></b>
</form>
</pre>
FORM;
echo $form;


// SHOW THE COOKIE ARRAY, IF ANY
echo '<pre>$_COOKIE CONTAINS '; var_dump($_COOKIE); echo "</pre>";



// UNRELATED FUNCTIONS TO TIDY UP FORM INPUT
function clean_string($string)
{
    return trim(preg_replace('/[^A-Z0-9_]/i', NULL, $string));
}

function clean_number($string)
{
    return trim(preg_replace('/[^0-9]/i',     0,    $string));
}

Open in new window

HTH, ~Ray
0
 
GaryCommented:
Ahh maybe I misunderstood, thought he was setting the cookie at a sub domain level name not site wide.
0
 
WebspeederAuthor Commented:
The cookies are set using .mysite.com. Setting the cookies is good, setting it with .mysite.com, I have access from xxx.mysite.com and yyy.mysite.com.

I need to be able to delete them all from one sub-domain.
0
 
WebspeederAuthor Commented:
The cookie is set in PHP or via Confluence, both cookies use CROWD for authentication and they are set to httpOnly so Javascript can't read them.
0
 
WebspeederAuthor Commented:
Ray,

I tried expiring the cookie with this line of code, but it doesn't appear to work. Do i have it wrong or will it not work across all the sub-domains to begin with?

document.cookie = 'cookie_name=; domain=.mysite.com; expires=Thu, 01 Jan 1970 00:00:01 GMT;';

I thought setting the "domain=" parameter would be the key.
0
 
leakim971PluritechnicianCommented:
1) maybenotyoursite.hosting.com
2) yoursite1.hosting.com
3) yoursite2.hosting.com

you say you want to delete all cookies of hosting.com but from 1,2 or 3 ? no way...
0
 
WebspeederAuthor Commented:
I can set the cookie for all the sub-domains, so you're saying I can't delete that same cookie from all the sub-domains at once?
0
 
WebspeederAuthor Commented:
not all cookies, a cookie with a particular name that is located on all sub-domains.
0
 
gr8gonzoConsultantCommented:
If you have a PHP page on all subdomains that simply deletes the cookie for that subdomain, then you can use JavaScript to dynamically create hidden frames and make the browser load those pages.
0
 
gr8gonzoConsultantCommented:
IFrames. Sorry, I gotta stop responding to questions via my phone.
0
 
Ray PaseurCommented:
The client side of the operation is JavaScript.  The server side is PHP.  For a variety of reasons that are too deep to go into in a Q&A forum like EE, these different sides interact in ways that produce security exposures.  Some of the background is available in this article:
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/A_11271-Understanding-Client-Server-Protocols-and-Web-Applications.html

You need to choose whether you will set and reset cookies in JavaScript OR PHP, but please do not try to make your choice work across the protocol boundaries.  You will be fighting an uphill battle.  Just pick one, and design your application layers so you can change quickly if the effect is not what you want.
0
 
Dave BaldwinFixer of ProblemsCommented:
I tried Ray's code above to demo that it would work on subdomains to set and delete cookies.  Except I ran into a couple of problems.  'number_format' didn't work for me and I think it's because it returns a float.  And the 'clean_number()' didn't work because it was stripping off minus signs.  Here's a modified version that does allow you to set negative lifetimes to set and delete cookies on subdomains.
<?php // RAY_cookie_example.php
error_reporting(E_ALL);

// RECEIVE FORM INPUT AND SET A COOKIE WITH THE NAME, VALUE AND LIFE FROM THE FORM
// MAN PAGE: http://php.net/manual/en/function.setcookie.php
// TO SEE COOKIES IN FIREFOX, FOLLOW SOMETHING LIKE TOOLS => OPTIONS => PRIVACY => SHOW COOKIES (OR "REMOVE INDIVIDUAL")


// REQUIRED AT PHP 5+
date_default_timezone_set('America/Los_Angeles');


// IF THE FORM HAS BEEN POSTED
if (!empty($_POST))
{
    // 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);
    $life = clean_number($_POST["life"]);
    //$life = $_POST["life"];

    // BE SURE WE HAVE USEFUL INFORMATION
    if ( ($name == '') || ($data == '') ) die("MISSING INPUT: PLEASE <a href=\"{$_SERVER['PHP_SELF']}\">TRY AGAIN</a>");


    // CHOOSE THE COOKIE NAME, VALUE, AND LIFE IN SECONDS
    $cookie_name    = $name;
    $cookie_value   = $data;
    $cookie_life    = $life;


    // CONFIGURE THE COOKIE LIFE
    if ($life == 0)
    {
        // USE THIS TO MAKE COOKIE EXPIRE AT END OF BROWSER LIFE
        $cookie_expires = 0;
    }
    else
    {
        // USE THIS TO MAKE A PERSISTENT COOKIE
        $cookie_expires = time() + $cookie_life;
    }


    // MAKE THE COOKIE AVAILABLE TO ALL DIRECTORY PATHS
    $cookie_path	= DIRECTORY_SEPARATOR;


    // 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 PHP_EOL . "<br/>SUCCESS!  THE COOKIE HAS BEEN SET AND WILL BE AVAILABLE TO THE NEXT PAGE LOAD";
    }
    else
    {
        echo PHP_EOL . "<br/>FAILURE!  THE COOKIE WAS NOT SET AS EXPECTED";
    }


    // AT THIS POINT, THE COOKIE HAS BEEN SET, BUT IT IS NOT AVAILABLE IN THIS SCRIPT
    // THE COOKIE WILL NOT BE RETURNED FROM THE CLIENT TO THE SERVER UNTIL THE NEXT HTTP REQUEST
    // THIS IS BECAUSE THE BROWSER SENDS THE COOKIE TO OUR SCRIPT BEFORE OUR SCRIPT STARTS RUNNING
    echo '<pre>';
    echo PHP_EOL . '$_COOKIE CONTAINS '; var_dump($_COOKIE);
    echo PHP_EOL . '$_POST CONTAINS ';   var_dump($_POST);
    echo PHP_EOL . 'THE COOKIE HAS BEEN SET WITH THESE VALUES: ';
    echo PHP_EOL . 'COOKIE NAME:    ' . $cookie_name;
    echo PHP_EOL . 'COOKIE VALUE:   ' . $cookie_value;
    // echo PHP_EOL . 'COOKIE EXPIRES: ' . number_format($cookie_expires) . " == " . date('r', $cookie_expires);
    echo PHP_EOL . 'COOKIE EXPIRES: ' . $cookie_expires . " == " . date('r', $cookie_expires);
    echo PHP_EOL . 'COOKIE PATH:    ' . $cookie_path;
    echo PHP_EOL . 'COOKIE DOMAIN:  ' . $cookie_domain;
    echo PHP_EOL . 'COOKIE SECURE:  '; var_dump($cookie_secure);
    echo           'COOKIE HTTP:    '; var_dump($cookie_http);
    echo "</pre>";
}


// END OF SETTING THE COOKIE - CREATE THE FORM IN HEREDOC NOTATION
$self = $_SERVER["PHP_SELF"];
$form = <<<FORM
<pre>
<form method="post">
COOKIE NAME: <input name="name" /> STRING
COOKIE DATA: <input name="data" /> STRING
COOKIE LIFE: <input name="life" /> INTEGER SECONDS
<input type="submit" />
<b>TO SEE THE EXISTING COOKIES <a href="$self">CLICK HERE</a></b>
</form>
</pre>
FORM;
echo $form;


// SHOW THE COOKIE ARRAY, IF ANY
echo '<pre>$_COOKIE CONTAINS '; var_dump($_COOKIE); echo "</pre>";



// UNRELATED FUNCTIONS TO TIDY UP FORM INPUT
function clean_string($string)
{
    return trim(preg_replace('/[^A-Z0-9_]/i', NULL, $string));
}

function clean_number($string)
{
    return trim(preg_replace('/[^0-9]-/i',     0,    $string));
}

Open in new window

0
 
WebspeederAuthor Commented:
"Expiring the same way it is created" is what led me to come up with a solution.

I was creating the cookie with PHP but trying to expire it with Javascript. Instead, I am running a PHP file to expire it and it works.

Here is the core of the PHP code for documentation purposes.

if (!empty($_COOKIE['cookie_name']))
{
      setcookie('cookie_name', '', time()-10, '/', '.mysite',false,true);
}

Thank you all for your responses.
0
 
Ray PaseurCommented:
@Dave:

Thanks for testing. Admittedly I have never tried to use that script to expire a cookie, so I will fix it to do that and push the new version to my teaching library.  PHP number_format() returns a string, but the string may contain formatting characters including comma and dot, so the function is probably out of place there, and simple (int) casting would be better.  It's always a little dicey when you accept external input and use it to set a cookie!

Best to all, ~Ray
0
 
Dave BaldwinFixer of ProblemsCommented:
You're welcome Ray, these things are good exercises for me to try to figure out why it doesn't do exactly what I thought it should.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.