Cookie gets deleted on restarting browser - php

The cookie which i set in codeigniter gets deleted after i restart the browser. I'm setting up a cookie like:
$test_cookie = array(
'name'=>'test',
'value'=> 'test',
'expire'=> time() + 60*60*24*14
);
$this->input->set_cookie($test_cookie);
The print_r($test_cookie) returns:
Array ( [name] => test [value] => test [expire] => 1309943188 )
Now i can print the cookie to make sure that the cookie is set:
$test_cookie= $this->input->cookie('test');
echo "<b> Cookie value: </b>". $test_cookie;
The cookie prints the value correctly.
However, if i restart the browser, i don't get the cookie value anymore. I've tried multiple browsers. With the var_dump, i get: bool(false)
Why the cookie is getting deleted when browser restarts?
Thanks.

The CodeIgniter documentation says the expires value is added to the current time. So effectively the expires value in your case is time() + time() + 60*60*24*14. This may be beyond the 32 Bit integer limit and turn into a negative value. This in turn will result in a temporary cookie that's deleted upon closing the browser.
$test_cookie = array(
'name'=>'test',
'value'=> 'test',
'expire'=> 60*60*24*14
);
should work. I think.

Related

Can't delete WordPress cookies

I am working on WordPress multisite, and I have changed the login functionality. However, it needs the users to delete old cookies before using this functionality I have created. So I am trying to clear the user's cookies by setting a new cookie, custom_wordpress_login_cookie, to know which of the users have old cookies in the browser, as shown in the following code.
add_action('init', 'clear_all_cookies_before_login');
function clear_all_cookies_before_login(){
if( ! isset( $_COOKIE['custom_wordpress_login_cookie'] ) ){
foreach( $_COOKIE as $key => $value ){
setcookie( $key, '', time() - YEAR_IN_SECONDS);
}
setcookie( 'custom_wordpress_login_cookie', 'true',
time() + YEAR_IN_SECONDS, '/', COOKIE_DOMAIN, false, true );
}
}
The new cookie is being set, but the old cookies persist. What could be the issue?
To prevent creation of a second cookie with the same name, pass / as the path argument to setcookie().
And so, you must change this line:
setcookie( $key, '', time() - YEAR_IN_SECONDS);
to:
setcookie( $key, '', time() - YEAR_IN_SECONDS, '/');
Also note that the way you're expiring cookies may not work if the user's system time is configured incorrectly. This is rare*, but does happen. A simpler way to expire cookies is to simply call:
setcookie( $key, '', 1, '/');
*the user would likely run into TLS issues if the webpage is served over HTTPS.
This is not an answer related to how you can clear cookies, but this solution will help you make sure that all the users currently logged into your website will need to login again.
Go in the wp-config.php and reset the secret salt keys. You can generate new ones here: https://api.wordpress.org/secret-key/1.1/salt/ .
That way it will force all of your users to login again and you no longer need to write code to delete the users' cookies.
Try: setcookie( $key, '', time() - 3600, '/', COOKIE_DOMAIN);
According WordPress documentation, it combines the salt keys with the password. The hash function mixes these up and gives a result. After that it stores inside a cookie to "remember" the login process or tracking behavior.
example: That's the reason two different usernames with the same password are successfully identified as different logins.
First you have to make distinct cookies for every user. Let's say custom_wordpress_login_cookie will contain inside a string with the username or any associated encoded string (preferred).
Then you will check if the custom_wordpress_login_cookie exists and contains the appropriate username.
Act accordingly, if found, perform your logic and then delete (unset) the cookie. Else create a new one.
The following code explains the flow...
function clear_all_cookies_before_login() {
// Current Time of visit
$time_now = date('F j, Y g:i a');
// Check a cookie already set
if(isset($_COOKIE['custom_wordpress_login_cookie'])) {
// Found Cookie
function check_visitor() {
// Retrieve information to use for your logic
$lastvisit = $_COOKIE['custom_wordpress_login_cookie'];
$string .= 'Since your last login '. $lastvisit .'. We have a tone of new things!';
// Delete the old cookie so that we can set it again with updated time
unset($_COOKIE['custom_wordpress_login_cookie']);
return $string;
}} else {
// Not found cookie
function check_visitor() {
$string .= 'Welcome to our website! Please login...' ;
return $string;
}
}
add_shortcode('New_Message', 'check_visitor');
// Set new cookie with expiration of 1 Day
setcookie('custom_wordpress_login_cookie', $time_now , time()+86400);
}
you must used first unset
unset( $_COOKIE[$v_username] );
setcookie( $v_username, '', time() - ( 15 * 60 ) );
Once that’s done, we will force the cookie to expire by setting its value variable to a null value (“”) and passing in a timestamp that’s in the past (time() - ( 15 * 60 )).
You are doing absolutely correct but the deletion of the cookie would not work. The above code will only expire the cookie in the current session. You have to destroy the session also if you want to make the old cookie dis-appear. Thus your new code would be like this:
add_action('init', 'clear_all_cookies_before_login');
function clear_all_cookies_before_login(){
if( ! isset( $_COOKIE['custom_wordpress_login_cookie'] ) ){
foreach( $_COOKIE as $key => $value ){
setcookie( $key, '', time() - YEAR_IN_SECONDS);
}
setcookie( 'custom_wordpress_login_cookie', 'true', time() + YEAR_IN_SECONDS, '/', COOKIE_DOMAIN, false, true );
//Destroy the session and re-direct the user to other location
//this will make sure to disappear the old cookie and new cookie
//only will remain
session_destroy();
header("Location:/");
}
}

Prevent cookie from getting other pages?

I don't want to allow getting cookie from other page ! I have been searched on internet but not really found or may be I don't know how to mention that case .How can I manage that ! I want to get null in test2.php but get cookie in test.php ?
test.php
<?php
setcookie("acc_id", "23A", time() + 3600, '/');
header("test.php");
var_dump($_COOKIE); // 'acc_id' => string '23A' (length=3)
?>
test2.php
<?php
var_dump($_COOKIE); // 'acc_id' => string '23A' (length=3)
You can use the $path parameter in the setcookie syntax.
setcookie("acc_id", "23A", time() + 3600, '/test.php');
Now if you try print_r($_COOKIE['acc_id']); from your test2.php, it will show you Undefined Index, which means the cookie is not set for that page.

Can PHP's setcookie take non-numeric keys? If so, why will this cookie not set?

I am trying to set a cookie as part of a login script but the cookies never seem to set. I've checked the code with copious debug points and the st cookie is called and setcookie responds true but on inspection no cookies exist. I've double checked by using chrome to look at my cookies - there are none there for this app.
The step before this checks for headers already sent so I know that is not the problem.
<?php
// ...
public function set_cookie($cookie,$value,$time=0){
$cookieCONF = core::get()->factory()->get_config('cookie',array('path'=>'/','domain'=>'.'));
core::get()->debug()->log("COOKIE[{$cookie}]", $value, FALSE, 7);
if($time!==0){
$time= time()+$time;
}
if(!is_array($value)){
setcookie($cookie, $value, $time, $cookieCONF['path'], $cookieCONF['domain']);
}else{
foreach($value as $val=>$ue){
core::get()->debug()->log("{$cookie}[{$val}]", $ue, FALSE, 8);
if(setcookie("{$cookie}[{$val}]", $ue, $time, $cookieCONF['path'], $cookieCONF['domain'])){
core::get()->debug()->log('COOKIE RESULT',"SET {$cookie}[{$val}]={$ue}", FALSE, 8);
}else{
core::get()->debug()->log('COOKIE RESULT',"NOPE {$cookie}[{$val}]={$ue}", FALSE, 8);
}
}
}
}
echoing out the values the function being called is:
setcookie("user[k]", "295f<SNIP>98f2", $time, "/~username/folder/", "localhost");
(Except with the path information for the user and folder in actual use).
This is the debug line that shows that setcookie() is returning true (success).
[15] => Array
(
[message] => COOKIE RESULT
[ref] => SET user[k]=295f<SNIP>98f2
)
So unless there is a limit to numeric keys only that I am unaware of I cannot see why these cookies refuse to set.
What have I done wrong?
Edit
Cookies can take non-numeric keys.
Changing the code to
setcookie("user[k]", "295f<SNIP>98f2", $time);
resulted in cookies being set. However, that set to too wide a scope.
Cookies can take non-numeric keys.
Changing the code to:
setcookie("user[k]", "295f<SNIP>98f2", $time);
resulted in cookies being set. Likewise:
setcookie("user[k]", "295f<SNIP>98f2", $time, "/~username/folder/");
was also fine.
It transpires that localhost cannot be explicitly set as domains must have at least two dots.
Cookies on localhost with explicit domain
So the problem here was not the code - it was setting the cookie but the browser was rejecting it.
Thus, setting localhost to null explicitly solved the problem.
public function set_cookie($cookie,$value,$time=0){
$cookieCONF = core::get()->factory()->get_config('cookie',array('path'=>'/','domain'=>'.'));
core::get()->debug()->log("COOKIE[{$cookie}]", $value, FALSE, 7);
if($time!==0){
$time= time()+$time;
}
if($cookieCONF['domain']=='localhost'){
$cookieCONF['domain']=null;
}
if(!is_array($value)){
setcookie($cookie, $value, $time, $cookieCONF['path'], $cookieCONF['domain']);
}else{
foreach($value as $val=>$ue){
core::get()->debug()->log("{$cookie}[{$val}]", $ue, FALSE, 8);
if(setcookie("{$cookie}[{$val}]", $ue, $time, $cookieCONF['path'], $cookieCONF['domain'])){
core::get()->debug()->log('COOKIE RESULT',"SET {$cookie}[{$val}]={$ue}", FALSE, 8);
}else{
core::get()->debug()->log('COOKIE RESULT',"NOPE {$cookie}[{$val}]={$ue}", FALSE, 8);
}
}
}
}

Cannot access session data

In my project, I'm trying to access the session data from 2 files, located in 2 different directories:
/site/page.extension.php <-- initializes the session and writes data to it
- also sets a cookie with session_id() and session_name()
/extension/ajax_handler.php <-- tries to access the session data, session_id()
- and session_name() are set via cookie and return the correct values
Now, my problem is, that even though session_id() and session_name() are the same in both files, I cannot access the session-array, it just returns an empty array.
My code:
page.extension.php:
session_start();
setcookie("psc_session", session_id(), strtotime("+20 minutes"), "/");
setcookie("psc_session_name", base64_encode(session_name()), strtotime("+20 minutes"), "/");
$_SESSION['uid'] = system::current_user_id();
ajax_handler.php:
session_id($_COOKIE['psc_session']);
session_name(base64_decode($_COOKIE['psc_session_name']));
session_start();
print_r($_SESSION); // => array(0) { }
I would really appreciate any help!
Greetings!
Update:
I've tried setting the session cookie params using this in page.extension.php:
$url = str_replace("http://", '', current_url(false)); // returns the current domain
session_set_cookie_params(10800, "/", $url, 0, 1);
If I now access session_get_cookie_params I receive (in ajax_handler.php):
print_r(session_get_cookie_params()); // =>
Array
(
[lifetime] => 0
[path] => /
[domain] =>
[secure] =>
[httponly] =>
)
Why does this happen?
I cannot replicate your problem, recreating the code you supplied the session variables and the cookies remain intact and are accessible from the ajax_handler.php. I'd suggest you backtrack and make sure both files are requested from the same domain.

How to get cookie's expire time

When I create a cookie, how to get cookie's expire time?
Putting an encoded json inside the cookie is my favorite method, to get properly formated data out of a cookie.
Try that:
$expiry = time() + 12345;
$data = (object) array( "value1" => "just for fun", "value2" => "i'll save whatever I want here" );
$cookieData = (object) array( "data" => $data, "expiry" => $expiry );
setcookie( "cookiename", json_encode( $cookieData ), $expiry );
then when you get your cookie next time:
$cookie = json_decode( $_COOKIE[ "cookiename" ] );
you can simply extract the expiry time, which was inserted as data inside the cookie itself..
$expiry = $cookie->expiry;
and additionally the data which will come out as a usable object :)
$data = $cookie->data;
$value1 = $cookie->data->value1;
etc. I find that to be a much neater way to use cookies, because you can nest as many small objects within other objects as you wish!
This is difficult to achieve, but the cookie expiration date can be set in another cookie. This cookie can then be read later to get the expiration date. Maybe there is a better way, but this is one of the methods to solve your problem.
You can set your cookie value containing expiry and get your expiry from cookie value.
// set
$expiry = time()+3600;
setcookie("mycookie", "mycookievalue|$expiry", $expiry);
// get
if (isset($_COOKIE["mycookie"])) {
list($value, $expiry) = explode("|", $_COOKIE["mycookie"]);
}
// Remember, some two-way encryption would be more secure in this case. See: https://github.com/qeremy/Cryptee
When you create a cookie via PHP die Default Value is 0, from the manual:
If set to 0, or omitted, the cookie
will expire at the end of the session
(when the browser closes)
Otherwise you can set the cookies lifetime in seconds as the third parameter:
http://www.php.net/manual/en/function.setcookie.php
But if you mean to get the remaining lifetime of an already existing cookie, i fear that, is not possible (at least not in a direct way).
It seems there's a list of all cookies sent to browser in array returned by php's headers_list() which among other data returns "Set-Cookie" elements as follows:
Set-Cookie: cooke_name=cookie_value; expires=expiration_time; Max-Age=age; path=path; domain=domain
This way you can also get deleted ones since their value is deleted:
Set-Cookie: cooke_name=deleted; expires=expiration_time; Max-Age=age; path=path; domain=domain
From there on it's easy to retrieve expiration time or age for particular cookie. Keep in mind though that this array is probably available only AFTER actual call to setcookie() has been made so it's valid for script that has already finished it's job. I haven't tested this in some other way(s) since this worked just fine for me.
This is rather old topic and I'm not sure if this is valid for all php builds but I thought it might be helpfull.
For more info see:
https://www.php.net/manual/en/function.headers-list.php
https://www.php.net/manual/en/function.headers-sent.php
To get cookies expire time, use this simple method.
<?php
//#############PART 1#############
//expiration time (a*b*c*d) <- change D corresponding to number of days for cookie expiration
$time = time()+(60*60*24*365);
$timeMemo = (string)$time;
//sets cookie with expiration time defined above
setcookie("testCookie", "" . $timeMemo . "", $time);
//#############PART 2#############
//this function will convert seconds to days.
function secToDays($sec){
return ($sec / 60 / 60 / 24);
}
//checks if cookie is set and prints out expiration time in days
if(isset($_COOKIE['testCookie'])){
echo "Cookie is set<br />";
if(round(secToDays((intval($_COOKIE['testCookie']) - time())),1) < 1){
echo "Cookie will expire today.";
}else{
echo "Cookie will expire in " . round(secToDays((intval($_COOKIE['testCookie']) - time())),1) . " day(s)";
}
}else{
echo "not set...";
}
?>
You need to keep Part 1 and Part 2 in different files, otherwise you will get the same expire date everytime.

Categories