Solved

How to delete cookie across a domain ...

Posted on 2014-01-29
20
357 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

 
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 110

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 35

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 35

Expert Comment

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

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 110

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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
Originally, this post was published on Monitis Blog, you can check it here . Websites are getting bigger and more complicated by the day. Video, images and custom fonts are all great for showcasing your product or service. But the price to pay in…
In this tutorial viewers will learn how to embed Flash content in a webpage using HTML5. Ensure your DOCTYPE declaration is set to HTML5: "<!DOCTYPE html>": Use the <object> tag to embed Flash content.: To specify that the object is Flash content, d…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

632 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