This has been an issue for me way too long. I always hated the fact that users are logged out almost every few hours. Compared to other sites on the www it was ridiculously short, no matter how long you set timeout and cookieTimeout in core settings.
I looked into it more than twice in the last year coming up with almost nothing. After many hours of investigating I just postponed it again for times unknown. It should be said that debugging the session/cookie based stuff – here Authentication – is quite a difficult past. Many things play into it making it hard to reproduce the issue.
The cake documentation also doesn’t tell us, that for php sessions to work this long it is also required to raise the internal max_lifetime. I stumpled across this by accident. Always thought this would be taken care of by cake itself. But after switching to database as session container I didn’t notice any improvements either. So the server side garbage collector maybe wasn’t responsible after all. At least not all alone.
So, to sum it up:
- Setting up timeouts was a waste of time
- Security level, as well (I just left it at low)
- Moving from php/cake to database didn’t work either – although it provides little more control
- Raising the php.ini settings for gc_maxlifetime didn’t work too well, either
I still get logged out after totally different lengths. Sometimes minutes, sometimes a few hours. It never lasts much longer. Not only a deadly problem for a social network running with Cake.
I tried multiple times to add an encrypted cookie as RememberMe functionally (to quicklogin such a logged out user again). But I failed – as I later found out due to a PHP bug with srand/mt_srand and suhosin (details).
Thanks to miles’ post regarding this bug I took a step forward and decided to take action (a lot of users have been complaining about unexplainable logouts the past months anyway).
Another not quire related problem is, that PHP (or Cake) stores the session cookies with a fixed expiring date. This date doesnt get updated with every request and therefore at some point will make the session cookie invalid. Nothing you can do about it at the moment…
AutoLogin? A way out?
I finally – after putting up with it for many years – adjusted Miles’ great spadework with his AutoLogin component to work with my apps.
Basically, this component saves the user data to a cookie on login. As soon as the session gets lost again (for whatever reason!?) the component re-logins the user. It happens silently without bothering the user.
The code can be found in my Tools plugin (the standalone rep. is deprecated).
Usage and Features
After successfully running it in a few cake2.x apps, I want to share the basic HOWTO. The only required thing to do is adding the component globally in AppController:
public $components = array('Session', 'RequestHandler', 'AutoLogin', 'Auth', ...);
It is important to include it before any AuthComponent to avoid getting any “not logged in” error messages triggered by it.
You can use /Config/configs.php (or any other Configure place) to define its settings:
$config['AutoLogin'] = array( 'controller' => 'account', 'username' => 'login', 'requirePrompt' => false ... //see the component for details on other options );
Please use the last one with caution. If requirePrompt is disabled you use AutoLogin for ALL logins. This requires users to always log out correctly in public places (especially in internet cafes this can be quite dangerous as others opening the site could hijack this logged in user even after several days). So make sure you use is only for sites where all users are properly informed and educated on this.
So for the default case you will need to add a checkbox into your login form:
if (Configure::read('AutoLogin.active')) { echo $this->Form->input('auto_login', array('type'=>'checkbox', 'label'=>__('Remember on this computer'))); }
That’s it. You can easily test it using database sessions and truncating the session table after login. It should log the user right back in as well as creating the new session table row. If everything is working right, the user shouldn’t even notice that he wasn’t logged in for a split second.
The if statement is optional. I use it to dynamically enable/disable the component based on the environment.
But if you use it, make sure you defined active as true in Configure.
Getting rid of the suhosin bug
As explained by Miles in the above links, most linux apache environments come with the suhosin patch which messes up srand by default. My localhost WAMP doesn’t. So there it worked right away. But to get it to work on the linux environment, all there is to do is:
In your /etc/php5/apache2/php.ini add this line at the bottom:
suhosin.srand.ignore = Off
And don’t forget to restart apache or at least /etc/init.d/apache2 force-reload.
TIP: I added a test case for this bug (see test file in the rep). Run it on every environment if you are not sure whether it is affected or not.
More tips
If you want to disable AutoLogin for specific sites you can simply set active to false for this site in your configs or dynamically in the controllers’ constructor.
Remember: Since you need to include it before Auth etc you cannot dynamically add it to the list of components. But you can always disable the included component this way
The debug mode is on auto-detect by default. If you develop locally (debug > 0) you have it enabled right away. But, of course, you can overwrite this value in your configs.
Another important setting is expires – it defaults to 2 weeks but can also easily be adjusted.
Alternatives
In 2.x there now are alternatives, as well. One is to use a custom CookieAuthenticate adapter for this.

Costa
February 8, 2012 at 08:17
Just FYI, I used Authsome and it includes "Remember me" functionality via a cookie (with a configurable expiry time).
https://github.com/felixge/cakephp-authsome
Gilles
February 29, 2012 at 23:32
Hey Mark,
I've also been running into this issue with Cake. Some time ago I found this article: http://blog.room34.com/archives/4521. Did you try what is described there?
Mark
February 29, 2012 at 23:38
I stopped using php as session type years ago. Due to that problem. But it still remained a mystery – even with DB sessions etc.
So in the end nothing really helped – and the session never lasted as long as it was supposed to.
Well, with the Cookie solution this is now over, anyway
Martin
July 19, 2012 at 02:24
Hi Mark
i was also spending a lot of hours with this without finding a solution. so i'm happy to see this
i cant get it work up to now.
i shoud be one of these reasons:
- i don't use username, but "email"
how should i tell this to the component?
'username' => 'email' ?
- i have defined in Auth authenticate like this:
'Auth'=>array(
'authenticate' => array(
'Form' => array(
'userModel' => 'User',
'fields' => array(
'username' => 'email',
'password' => 'password'
),
'scope' => array(
'User.enabled' => 1,
'User.user_role_id in (1,2)'
)
)
),
do i have to change something in this config?
would be very happy about some help
Mark
July 19, 2012 at 09:31
exactly – I have an app with email, too.
with the same settings you have. that is supposed to work.
Martin
July 19, 2012 at 13:21
Thanks Mark, now it seems to work.
But i can't find the cookie in my browser preferences… does it save the cookies in other places??
I have debug on and the email for debug also configured, but never see debug infos…
Martin
July 19, 2012 at 13:33
now i get the debug info via email.
do you know why i can't see the cookie (f.e. in firefox preferences cookies)?
Mark
July 19, 2012 at 13:36
for local development.
You should find it under the local url, though. at least I do.
Martin
July 19, 2012 at 14:02
that's it!
thanks very much mark!
Martin
July 19, 2012 at 16:39
it works, but now i get a 'Cookie Mismatch' error in email, everytime i navigate in my app (click on links) to a page which doesn't requiere a login (f.e. pages/home, forgot password, etc..)
if i am loged in, there are no 'Cookie Mismatch' errors.
do you have an idea how i can get rid of that?
(if you are interested in seeing the site, i can give you the url by email).
EveConnected
October 13, 2012 at 12:02
Hi, after adding the Component, I can't log in anymore. Because the salted PW doesn't match the salted PW in the database anymore.
Any idea how this can happen. Could be not related to the Component, but is strange.
Mark
October 13, 2012 at 12:24
I dont think it does.
You would need to show your setup. But i am fairly certain that the component is separate from the normal login.
Travis
May 22, 2013 at 21:05
I'm using this component in your Tools object and it creates the cookie fine. Doesn't seem to be doing the autologin though, like it's not respecting that the cookie is there. Any ideas?
Danny Lieberman
May 28, 2013 at 08:01
Great stuff.
Just to update you on the Suhosin thing. It's not enough to play with the srand parameters on the Suhosin extension – you need to turn off transparent session and cookie encryption – this definitely breaks Cake 2.3 / PHP persistent sessions
suhosin.session.encrypt = Off
suhosin.cookie.encrypt = Off
suhosin.srand.ignore = Off
suhosin.mt_srand.ignore = Off