Cookie not setting in php version 7.4 using option array? - php

I am trying to get my a cookie to work within an iframe on another site url.
But when I add this new method of setting cookie options in an array, the cookie is not setting at all even not viewing in the iframe.
Here is my previous php set cookie which works fine on its own url, but does not work in iframe.
public function authenticate()
{
$this->loadCrypt();
setcookie(
'_siteauth',
Crypt::encrypt(site()->password),
time() + 86400,
'/'
);
return true;
}
Then here is my new version thats not working when outputting options as an array as per php docs for 7.3 above.
public function authenticate()
{
$this->loadCrypt();
setcookie(
'_siteauth',
Crypt::encrypt(site()->password),
[
'expires' => time() + 86400,
'path' => '/',
'samesite' => 'None'
]
);
}
The syntax above is exactly the same as the one in this question...
How to fix "set SameSite cookie to none" warning?
I'm getting no errors, the second set cookie method is not even setting a cookie, when the first one at least sets, just not when not inside an iframe on a different domain.
Any ideas would be great thanks.
Checked response header and there is a warning icon against Set-Cookie which I didn't have originally. But it doesn't tell me what the error is and why?

Related

PHP Session Cookie With Security Flags & Extendable Expiry - Best Way?

Okay so I've created a login system using PHP Sessions which stores user-related data within $_SESSION while logged in. To reach a PHP $_SESSION / session cookie whose expiry gets extended by x seconds every time the client refreshes a page, I created the following callback, which I call upon every page initiation:
<?php
if ( session_status() === PHP_SESSION_NONE ) {
session_start(
[
'cookie_path' => '/',
'cookie_domain' => 'mydomain.com',
'cookie_secure' => true,
'cookie_httponly' => true,
'cookie_samesite' => 'Strict',
'use_strict_mode' => true,
'use_trans_sid' => false,
'use_only_cookies' => true
]
);
} else {
// If session already exists, simply take it up again without overwriting parameters
session_start();
}
// Then determine the lifetime of the cookie (was only able to make the session cookie
// lifetime expendable using this syntax, as explained in the [first example of the php docs](https://www.php.net/manual/de/function.session-set-cookie-params.php)
setcookie(
session_name(),
session_id(),
[
'expires' => time() + x,
'path' => '/',
'domain' => 'mydomain.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]
);
?>
The reason why I specify all the:
httponly
secure
cookie path
cookie domain
samesite
parameters upon the very first call of session_start() AND also in the call of setcookie() is because if I specify one of them in session_start() and not in setcookie() or vice-versa, the browser returns two session cookies with the same session IDs, one having all of the mentioned flags, and the other without:
Now the problem is that, when I logout via the following callback, which I call as specified in the docs:
<?php
// Called via PHP Form Submit
session_start();
setcookie(
session_name(),
'',
time() - 42000,
'/',
'mydomain.com',
true,
true
);
session_destroy();
header( 'Location: mydomain.com' );
?>
I get the same problem as described in the images above; two session cookies in my browser, and again one having all the flags set, the other not, and the one without the flags set having set its expiry to the session's end, and the other one with its expiry set in x seconds; all exactly as in the image.
What am I doing wrong?
UPDATE
Is it may better to actually set all of the session cookie parameters via the php.ini file, and handle the session cookie expiry via a timestamp within $_SESSION, done like in this example?? Just thinking of a way of making the provision of any parameters in session_start() + any calls to setcookie() obsolete..
So my question is basically:
What's actually the best way of using several PHP session cookie flags, combined with a session expiry which is limited to let's say 10 mins, which gets refreshed by 10 mins on every page load?

Why do my cookies expire instantly?

I have a function that sets cookies; in this function I use PHP's setcookie function in order to set cookies, for example:
setcookie('auth', $token, time() + 3600);
The function I'm using setcookie in is as follows:
function SetAuthenticationCookie($id, $rememberme) {
$token = md5(uniqid(mt_rand(), true));
executeNonUserQuery([db query]);
if ($rememberme) {
setcookie('auth', $token, time() + (86400 * 90));
setcookie('profid', $id, time() + (86400 * 90));
}
else
{
setcookie('auth', $token, time() + 3600);
setcookie('profid', $id, time() + 3600);
}
}
The above cookie should be valid for one hour, and appears this way in the browser (see below screenshot).
In the browser the cookies show before it redirects (the page is dynamic), therefore the cookies are being set. However they disappear when the page redirects. This causes a problem because the main UI page (where the login page redirects) checks for the presence of the authentication cookies and redirects back to the login page if they don't exist.
I followed the official documentation for setcookie and am unable to see what the problem is. Chrome reports that the cookie path is /internal therefore it's a possibility that the actual page can't access them (the page path is /pages), but this still doesn't explain why they disappear completely from Chrome.
The cookie is set to expire in an hour after it is set, but this doesn't explain the disappearance of the cookies unless I'm missing something crucial in setcookie concerning the setting of the expiration time. I experience the same issue in other browsers, so it has to be something that I've done wrong or missed.
I confirm that I have nothing that unsets or expires the cookies (I haven't implemented that yet). I've tried setting the path to / but this doesn't fix the problem.
What am I doing wrong, and how can I fix it?
I'm aware of the security issues here, my priority is to fix this problem first.
This issue was caused by two factors:
The cookie path
PHP's timezone
As mentioned in the question I had already tried setting the cookie path to / with no effect. However I did not consider PHP's timezone, which was set to UTC.
Setting the timezone to the correct Europe/Guernsey plus setting the cookie path to / (root) fixed the issue.
Ok, add a path and make it available to the whole website rather than just the folder the first script is in
setcookie('auth', $token, time() + 3600, '/');

Setting cookie by PHP and reading using JavaScript

I use the Laravel PHP framework and set a cookie using Cookie::put(..),
Code to set cookie using Laravel PHP,
Cookie::put('id', $id , 0, '/');
when I looked into it I found cookie is being set to a root path that's good for me.
Now in JS I use a jQuery plugin to read the cookie but it returns null while reading cookie setted by PHP.
JS code to access cookie,
function getCookie(c_name)
{
var i,x,y,ARRcookies=document.cookie.split(";");
for (i=0;i<ARRcookies.length;i++)
{
x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
x=x.replace(/^\s+|\s+$/g,"");
if (x==c_name){
return unescape(y);
}
}
}
print_r($_COOKIE)
Array ( [id] => 653a8dbd0903d2eacfdfe87bce29640d136a4380+1 [session_payload] => 2c3e260bb766ea1519dcbc3d13025d3ede6e2e63+mSfAHUAPvmFefQbIArozzbQfY0IzZpAeTarpQsHHOseN+SD3xmmUWfUduVYWf7qVu1Rwo2XYIBSBTUt+J1DhbE9sN2yEelpjsHzU0CVw3F1aPpcPh6oSTzIfskr2hHuWIGi5sf1lvD7qRHtcjPOBD700vnQSy2+DIMTNT4eMS7pz85zi9TMpgLQfWbtUUtNQk1SRHwncwgQyp1xhgPqp4d6eLjaZQ2hXBtOgYbC2Ty5xS4e76WCW+dumNMj3hkSfMoDssKnmRTzV7jYUT6a+oH26tZkKOR8EMMh04xHMWlt73aFsL9EZrIXZFKHkOXqU883qThWot//emOpakBKWyA== [laravel_session] => 2729bdfca6fe6e6f3c98d03c11a65915649af09b+ML1G6xZ5YkImViUxm9gOaTo5AT8jyBfqagdoeyAs ) 1
Update:
I really don't know why this was voted down but here,
I want to access the cookie using JS previously added using PHP.
If COOKIE expiry set to 0, the cookie will expire at the end of the session (when the browser closes). So, JS will not read expired COOKIEs
Try setting the COOKIE expiration for longer,
Cookie::put('id', $id , time()+3600, '/'); //set the cookie alive for 1 hour

Codeigniter Cookie Issue

Cookies arent being set in my first view.
Is this how it should be ? or am I mistaken
Please view the code below for further illustration:
if( !get_cookie('rate') ){
$cookie_rate = array(
'name' => 'rate',
'value' => '10',
'expire' => '100000'
);
set_cookie($cookie_rate);
}
var_dump( get_cookie('rate') ); //returns ( boolean false )
if( !isset($_COOKIE['foo']) ){
$_COOKIE['foo'] = 'bar';
}
var_dump( $_COOKIE['foo'] ); // This yields string 'bar' (length=3) on the first visit
Doing the same thing with php cookies yeilds an array with cookie values.
This problem persists only in the first visit of a page.
This isn't a CodeIgniter vs PHP issue. You just don't understand how cookies work.
Cookies are a header sent by the server which the browser must send back on subsequent requests. $this->input->set_cookie() and set_cookie() send a cookie header.
$_COOKIES on PHP (and thus $this->input->cookie() and therefore the get_cookie() helper) only contain cookies which the browser sent.
Thus when you set a cookie with set_cookie(), you won't be able to get_cookie() until the browser's next request.
Seeing as CI's set_cookie probably utilizes the same mechanism as PHP's setcookie(), this entry from the manual probably applies:
Common pitfalls
Cookies will not become visible until the next loading of a page that the cookie should be visible for. To test if a cookie was successfully set, check for the cookie on a next loading page before the cookie expires. Expire time is set via the expire parameter. A nice way to debug the existence of cookies is by simply calling print_r($_COOKIE);.
I can't see any mention of this behaviour in the CI manual, but it's likely to be the same thing.
If I understood this right youre trying to see the data of the cookie before reloading the page which won't work. Try setting the cookie, reloading the page and then checking the cookie for data.
Also sometimes you need to specify domain and such, perhaps it doesn't apply right now but it might be nice to know later if they suddenly stop working, from CI-documentation:
$cookie = array(
'name' => 'The Cookie Name',
'value' => 'The Value',
'expire' => '86500',
'domain' => '.some-domain.com',
'path' => '/',
'prefix' => 'myprefix_',
'secure' => TRUE
);
$this->input->set_cookie($cookie);
Also, consider using the session class instead of cookies if you don't need anything specifically from cookies since they are more secure. http://codeigniter.com/user_guide/libraries/sessions.html
Thats probably not the problem, in fact thats how cookie works, its set and on next page load it seems to be visible from then.

cookie delete problem

I have two simple functions to set and clear cookie.
private function _setCookie($value = null) {
$value = $value === null ? $this->getRandomId() : $value;
setcookie($this->getName(), $value, time()+10800, '/');
}
private function _clearCookie() {
setcookie($this->getName(), '', time()-10800, '/');
}
There is a page when accessed starts session and create a cookie as desired. When redirect call happens from different server to my page , delete cookie function calls internally above _clearCookie funtion.I checked setcookie returns true and I also tried to unset cookie in same method but cookie is still available when I reload page. I still can find that cookie in browser as well as firebug and print_r($_COOKIE)
Also I changed expire time to time()-(3600*24) as mentioned is some others threads but no change in my case. What am I missing here?
so when I mentioned 'redirect call happens from different server to my page' I was trying to mention it as back channel call. And being a back channel call, browser cookies were not getting identified I suppose and that is the main reason even if setcookie returns me true, actual cookie deletion from browser would never happen in such cases.

Categories