views:

163

answers:

0

I found some interesting behavior with the CakePHP Cookie Component in my app today. It all started with a logout bug. My app was essentially allowing users to refresh the page and be re-logged-in if they had opted to "Remember me" (sets cookie). But it was only for that session. Next visit (new session), the bug would not appear - i.e. it "forgot them".

After careful review, and about a dozen echo lines, I found something that didn't seem so intuitive to me. Even though I had called destroy() on the cookie for the logout, read() was still returning a value. In my case, this was resetting the session and re-logging-in the user. This appears to be due to some logic in the read() method of the Cookie component (~ line 241). So even though I called destroy(), technically the PHP super-global $_COOKIE still had a stale version which was then read and returned.

I don't want to go so far as to call this a bug. But to me it is unexpected behavior. If you write a wrapper class (component), and call write(value), delete(value)/destroy(), and read(value), I'd like to think read(value) does not return anything. This seems intuitive, would you agree?

I imagine not many people see this odd behavior because typically you redirect the user after a logout action. But all the same, I think some additional $_COOKIE cleanup or logic adjustments should be added to the Cookie component.

Here's my code:

if (isset($this->params['pass'][0]) && $this->params['pass'][0] == 'logout') {
    // logout was sent, kill session and any cookies
    $this->Session->destroy();
    $this->Cookie->destroy();
    $message = 'You have been logged out.';
    $logout = true;
}

// more beforeFilter code...

if (!$logout && $this->Cookie->read('sessUID')) {
    // auto login user from cookie
    // NOTE: only do this if $logout due to weak Cookie::destroy()
    $this->Session->write('sessUID', $this->Cookie->read('sessUID'));
}