I have a problem with unsetting cookies. At the moment, i am unable to log out. Cookies itself works like a charm while validating user session.
So upon first login i am setting cookies in this way (on successful login):
$cookie_username = $username;
$cookie_password = sha1(md5($password));
$cookie_value = 'username='.$cookie_username.'&hash='.$cookie_password;
$cookie_name = 'remember_me#website';
$cookie_time = time() + 31536000;
setcookie($cookie_name, $cookie_value, $cookie_time, '/', '.website.com');
Cookies above work well and i dont have problems with reading them.
This is my logout code:
setcookie($cookie_name, '', time()-3600, '/', '.website.com');
unset($_COOKIE[$cookie_name]);
unset($_SESSION['username']); \
unset($_SESSION['loggedin']); / were setted after successful login
According to what i have read around SO this should work and delete cookies, however they dont :(
You have to be sure the cookie's name, domain, path, and even security settings are all identical to what you're attempting to delete.
If you created the cookie like this:
setcookie('name', 'value', time()+3600);
and then attempted to delete it like this:
setcookie('name', 'value', time()-3600, '/', '.website.com');
That won't work. You have to have the exact same parameters that were used when creating the cookie.
If you created the cookie in JavaScript, double-check your settings there.
As a test, try all of the following code. If it works, comment out each one-by-one, until you're only left with the one that worked:
setcookie($cookie_name, '', time()-3600);
setcookie($cookie_name, '', time()-3600, '/');
setcookie($cookie_name, '', time()-3600, '/', '.website.com');
setcookie($cookie_name, '', time()-3600, '/', '.website.com', 1);
I've got a problem, user can't Log Out because the $_COOKIE's are not actually deleting. I can't find out what could be the problem.
This code is used only once at Log In:
// Log In
$_SESSION['user_id'] = $row['user_id'];
$_SESSION['username'] = $row['username'];
setcookie('user_id', $row['user_id'], time() + 2592000);
setcookie('username', $row['username'], time() + 2592000);
The code below is checking if cookies are set up to make users to be logged in when they relaunch their browser (the "keep me logged in" effect).
// Starting Session
session_start();
// If the session vars aren't set, try to set them with cookies
if (!isset($_SESSION['user_id'])) {
// This check always equals true because cookies are not deleting on Log Out
if (isset($_COOKIE['user_id']) && isset($_COOKIE['username'])) {
$_SESSION['user_id'] = $_COOKIE['user_id'];
$_SESSION['username'] = $_COOKIE['username'];
}
}
This code is launched only once on Log Out:
// Log Out
session_start();
if (isset($_SESSION['user_id'])) {
$_SESSION = array();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 2592000, '/');
}
session_destroy();
}
setcookie('user_id', '', time() - 2592000);
setcookie('username', '', time() - 2592000);
Don't use relative times for cookies. if you want to expire a cookie, then use Jan 1 1970 00:00:00. You're assuming that the user's clock is accurate and within an hour of your server's. Given how many people have their VCRs blinking 12:00, this is a bad assumptiong.
As well, why are you storing login information in a client-side cookie? The only cookie you should really be setting is the session cookie, which session_start() already does for you, then store all that information in $_SESSION only.
I think you're doing it way too complicated.
My example where it's just an admin login:
login.php
#session_start();
if (isset($_GET['login'])) {
if($_GET['name'] == $s['admin']){
if($_GET['pw'] == $s['adminpw']){
$_SESSION['isadmin'] = true;
}
}
}
logout.php
#session_start();
unset ($_SESSION['isadmin']);
use session_set_cookie_params() to set the lifetimes
I found why cookies were not removing!
To make sure your cookies will remove, set the same path on removing cookies as on setting them.
// Setting Cookie
setcookie(session_name(), '', time()-2592000, '/'); // The path here is "/"
// Removing Cookie
setcookie(session_name(), '', time()+2592000, '/'); // The path here is "/"
I want make a simple referral system. Basically referral URL structure something like this.
http://domain.com/?ref=abc
http://domain.com/about-us/?ref=abc
http://domain.com/slug/more-slug/?ref=abc
How do I validate if no cookie found, script will set default cookie to $_COOKIE['referral'] = 'generic'
If cookie already exists just keep it.
Here what I've done but it always replace to generic if no referral found although previously already having it.
if (!isset($_COOKIE['referral'])) {
setcookie('referral', 'generic', time() + 31536000);
} else if (isset($_GET['ref']) && !empty($_GET['ref'])) {
$ref = trim(secure($_GET['ref']));
setcookie('referral', $ref, time() + 31536000);
}
if(!isset($_COOKIE['referral'])){
if(isset($_GET['ref']) && !empty($_GET['ref'])) {
$ref = trim(secure($_GET['ref']));
setcookie('referral', $ref, time() + 31536000);
}else{
setcookie('referral', 'generic', time() + 31536000);
}
}
you could remove isset($_GET['ref']) cause you check !empty($_GET['ref'])
I have a login/logout system and need the cookies to work across www.mydomain.com as well as mydomain.com. The problem I'm having is on deleting the cookies. On the login I am setting the cookies like this:
session_start();
//set session vars
setcookie('user_id', $row['user_id'], time() + (60 * 60 * 24 * 30), '/', 'domain.com');
setcookie('full_name', $row['first_name']." ".$row['last_name'], time() + (60 * 60 * 24 * 30), '/', 'domain.com');
Which works, and the cookies are saved and it works with or without the www. It allows the profile page to be viewed which has this code:
session_start();
if(!isset($_SESSION['user_id'])) {
if(isset($_COOKIE['user_id']) && isset($_COOKIE['full_name'])) {
$_SESSION['user_id'] = $_COOKIE['user_id'];
$_SESSION['full_name'] = $_COOKIE['full_name'];
}
}
if(!isset($_SESSION['user_id'])) {
echo '<p class="login">Please log in to access this page.</p>';
exit();
}
The problem is logging out:
session_start();
if(isset($_SESSION['user_id'])) {
$_SESSION = array();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 3600, '/', 'domain.com');
}
session_destroy();
}
setcookie('user_id', '', time() - 3600, '/', 'domain.com');
setcookie('full_name', '', time() - 3600, '/', 'domain.com');
The cookies are deleted but only for the current domain. So if I login from domain.com/login.php and logout from domain.com/logout.php, domain.com/profile.php doesnt work (good) but I will still be able to view www.domain.com/profile.php if I have visited the www. version before logging out. And vice versa I can logout from www.domain.com/logout.php and still be able to view domain.com/profile.php. Is there a way to delete all cookies across the subdomains?
Use '.domain.com' instead 'domain.com' to work with all subdomains.
The OP wrote in a comment:
Finally figured it out, the session was creating a separate cookie when the subdomain was changed. So logging out would delete one session cookie but leave the other. The solution was to name the session before starting it so it always has the same name:
$some_name = session_name("cool_session");
session_set_cookie_params(0, '/', '.domain.com'); session_start();
I'm wondering if I can delete all my website's cookies when a user click on logout, because I used this as function to delete cookies but it isn't work properly:
setcookie("user",false);
Is there a way to delete one domain's cookies in PHP?
PHP setcookie()
Taken from that page, this will unset all of the cookies for your domain:
// unset cookies
if (isset($_SERVER['HTTP_COOKIE'])) {
$cookies = explode(';', $_SERVER['HTTP_COOKIE']);
foreach($cookies as $cookie) {
$parts = explode('=', $cookie);
$name = trim($parts[0]);
setcookie($name, '', time()-1000);
setcookie($name, '', time()-1000, '/');
}
}
http://www.php.net/manual/en/function.setcookie.php#73484
$past = time() - 3600;
foreach ( $_COOKIE as $key => $value )
{
setcookie( $key, $value, $past, '/' );
}
Even better is however to remember (or store it somewhere) which cookies are set with your application on a domain and delete all those directly.
That way you can be sure to delete all values correctly.
I agree with some of the above answers. I would just recommend replacing "time()-1000" with "1". A value of "1" means January 1st, 1970, which ensures expiration 100%. Therefore:
setcookie($name, '', 1);
setcookie($name, '', 1, '/');
The provided Answers did not solve my problem,
It did not:
Remove parent domain cookies (from a.b.c; remove b.c; cookies),
Remove cookies from a higher path other then root.
My script does, see.
<?php function unset_cookie($name)
{
$host = $_SERVER['HTTP_HOST'];
$domain = explode(':', $host)[0];
$uri = $_SERVER['REQUEST_URI'];
$uri = rtrim(explode('?', $uri)[0], '/');
if ($uri && !filter_var('file://' . $uri, FILTER_VALIDATE_URL)) {
throw new Exception('invalid uri: ' . $uri);
}
$parts = explode('/', $uri);
$cookiePath = '';
foreach ($parts as $part) {
$cookiePath = '/'.ltrim($cookiePath.'/'.$part, '//');
setcookie($name, '', 1, $cookiePath);
$_domain = $domain;
do {
setcookie($name, '', 1, $cookiePath, $_domain);
} while (strpos($_domain, '.') !== false && $_domain = substr($_domain, 1 + strpos($_domain, '.')));
}
}
It is not the most pretty/safe/optimal solution, so use this only if you do not known the cookie-path and/or cookie-domain's. Or use the idea in order to create your version.
make sure you call your setcookie function before any output happens on your site.
also, if your users are logging out, you should also delete/invalidate their session variables.
When you change the name of your Cookies, you may also want to delete all Cookies but preserve one:
if (isset($_COOKIE)) {
foreach($_COOKIE as $name => $value) {
if ($name != "preservecookie") // Name of the cookie you want to preserve
{
setcookie($name, '', 1); // Better use 1 to avoid time problems, like timezones
setcookie($name, '', 1, '/');
}
}
}
Also based on this PHP-Answer
You should be aware of various tracking tools like Google Analytics also use cookies on your domain and you don't want to delete them, if you want to have correct data in GA.
The only solution I could get working was to set the existing cookies to null. I couldn't delete the cookies from the client.
So for logging a user out I use the following:
setcookie("username", null, time()+$this->seconds, "/", $this->domain, 0);
setcookie("password", null, time()+$this->seconds, "/", $this->domain, 0);
Of course this doesn't delete ALL cookies.
All previous answers have overlooked that the setcookie could have been used with an explicit domain. Furthermore, the cookie might have been set on a higher subdomain, e.g. if you were on a foo.bar.tar.com domain, there might be a cookie set on tar.com. Therefore, you want to unset cookies for all domains that might have dropped the cookie:
$host = explode('.', $_SERVER['HTTP_HOST']);
while ($host) {
$domain = '.' . implode('.', $host);
foreach ($_COOKIE as $name => $value) {
setcookie($name, '', 1, '/', $domain);
}
array_shift($host);
}
Use the function to clear cookies:
function clearCookies($clearSession = false)
{
$past = time() - 3600;
if ($clearSession === false)
$sessionId = session_id();
foreach ($_COOKIE as $key => $value)
{
if ($clearSession !== false || $value !== $sessionId)
setcookie($key, $value, $past, '/');
}
}
If you pass true then it clears session data, otherwise session data is preserved.
I know this question is old, but this is a much easier alternative:
header_remove();
But be careful! It will erase ALL headers, including Cookies, Session, etc., as explained in the docs.
<?php
parse_str(http_build_query($_COOKIE),$arr);
foreach ($arr as $k=>$v) {
setCookie("$k","",1000,"/");
}
I had to add the following to the top answer to actually remove a few cookies that wouldn't go away:
foreach($_COOKIE as $cook) {
setcookie($cook, '', time()-1000);
setcookie($cook, '', time()-1000, '/');
}