Solved

How to delete cookie across a domain ...

Posted on 2014-01-29
20
345 Views
Last Modified: 2014-01-30
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;';
0
Comment
Question by:Webspeeder
  • 6
  • 5
  • 3
  • +3
20 Comments
 
LVL 58

Expert Comment

by:Gary
ID: 39819684
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
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 39819712
Sorry, that's backwards.  ".mysite.com" is supposed to be available on all subdomains.  http://en.wikipedia.org/wiki/HTTP_cookie#Cookie_attributes
0
 
LVL 58

Expert Comment

by:Gary
ID: 39819722
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
Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 39819729
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
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 39819737
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
 
LVL 58

Expert Comment

by:Gary
ID: 39819759
Ahh maybe I misunderstood, thought he was setting the cookie at a sub domain level name not site wide.
0
 

Author Comment

by:Webspeeder
ID: 39819785
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
 

Author Comment

by:Webspeeder
ID: 39819787
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
 

Author Comment

by:Webspeeder
ID: 39819793
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
 
LVL 82

Expert Comment

by:leakim971
ID: 39819798
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
 

Author Comment

by:Webspeeder
ID: 39819819
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
 

Author Comment

by:Webspeeder
ID: 39819821
not all cookies, a cookie with a particular name that is located on all sub-domains.
0
 
LVL 83

Accepted Solution

by:
Dave Baldwin earned 500 total points
ID: 39819857
"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
 
LVL 34

Expert Comment

by:gr8gonzo
ID: 39819910
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
 
LVL 34

Expert Comment

by:gr8gonzo
ID: 39819912
IFrames. Sorry, I gotta stop responding to questions via my phone.
0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 39819916
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
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 39820102
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
 

Author Closing Comment

by:Webspeeder
ID: 39820518
"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
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 39820648
@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
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 39821758
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

Featured Post

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article discusses four methods for overlaying images in a container on a web page
This article discusses how to create an extensible mechanism for linked drop downs.
In this tutorial viewers will learn how to style a corner ribbon overlay for an image using CSS Create a new class by typing ".Ribbon":  Define the class' "display:" as "inline-block": Define its "position:" as "relative": Define its "overflow:" as …
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

773 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