-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Description
This is a (multiple allowed):
-
bug
-
enhancement
-
feature-discussion (RFC)
-
CakePHP Version: 3.5.2
-
Platform and Target: Apache/2.4.12 (Win32) OpenSSL/1.0.1l PHP/5.6.8
What you did
I tried to port my previous "remember me" cookie implementation (based on Cookie Component) to the new Cookie management.
My codebase is pretty simple:
$this->response = $this->response->withCookie(
(new Cookie('urmc'))
->withValue([
'user_id' => $user_id,
'token' => $token,
])
->withExpiry(new DateTime('+1 month'))
->withHttpOnly(true)
);
return $this->redirect('/');I had 3 problems:
Cookie with redirect
If I set the cookie before a redirect, it doesn't set any cookie.
I tried to debug ResponseEmitter.php: in the function emitHeaders() it seems to resets the value of the variable $cookies right after setting a header of type 'Location: ...'.
For debug purpose I tried to temporarily remove the redirect like this:
foreach ($response->getHeaders() as $name => $values) {
if (strtolower($name) === 'set-cookie') {
$cookies = array_merge($cookies, $values);
continue;
}
if (strtolower($name) === 'location') {
continue;
}
...and then $cookies correctly had the cookie i setted.
Cookie with value of type array
After I removed the redirect, it gave me another error:
setcookie() expects parameter 2 to be string, array given
This is because it calls Response->convertCookieToArray() that doesn't convert values of type array to string.
But I saw that Cookie() object can handle values of type array by using an internal variable $isExpanded... is this correct?
I expected that I could set a cookie with value of type array without the need to explicitly call json_encode()
Encrypted Cookie
I don't know if I'm using it incorrectly, but EncryptedCookieMiddleware only decodes my cookie and doesn't encode it.
This is my code (in routes.php):
Router::scope('/', function (RouteBuilder $routes) {
...
$routes->registerMiddleware('csrf', new CsrfProtectionMiddleware());
$routes->registerMiddleware('cookies', new EncryptedCookieMiddleware(['urmc'], Configure::read('Security.cookieKey')));
$routes->applyMiddleware('csrf', 'cookies');
...
$routes->fallbacks(DashedRoute::class);
});Maybe I didn't understand really well how middleware works, but there is only a __invoke() function that calls both decodeCookies() in the request and encodeCookies() in the response...
But I set the cookie after that, right? So the cookie doesn't encode because the __invoke() function has already been called?
Thank you