CakePHP Session Timeout on Inactivity only
Asked Answered
I

5

25

So the crux of this question is just how to prevent CakePHP from de-authenticating a session ONLY after a period of inactivity.

So, if the user does nothing then I expect CakePHP to log them out after a period of 30 minutes. However, if the user chooses to visit a page on the 28th minute of inactivity, then CakePHP should 'reset' it's timeout counter.

This currently isn't happening. Regardless of activity, CakePHP times out after the specified time in my core configuration (app/Config/core.php).

Here's my config code:

Configure::write('Session', array(
    'defaults' => 'cake',
    'timeout' => '30'
));

Any ideas?

Inspect answered 22/1, 2013 at 23:35 Comment(0)
M
28

After running into the same problem I've found that this was caused by the Session.cookieTimeout value. Although the php session was still valid, the expiration date on the session cookie does not get refreshed.

This is now my session config

Configure::write('Session', array(
        'defaults' => 'php',
        'timeout' => 30, // The session will timeout after 30 minutes of inactivity
        'cookieTimeout' => 1440, // The session cookie will live for at most 24 hours, this does not effect session timeouts
        'checkAgent' => false,
        'autoRegenerate' => true, // causes the session expiration time to reset on each page load
    ));
Matrilineage answered 21/5, 2013 at 10:19 Comment(9)
What would happen after 1440 minutes with this configuration if someone used the site every 20 minutes? (i.e. the timeout didn't kick in)Verlaverlee
@Matt, It would definitely kick the user out! If you genuinely believe that you are going to have users on your site for 24hrs+ then you'll either need to extend the cookieTimeout value to something suitable for you, or manually extend the cookie expiry time through PHP.Matrilineage
I thought that the 1440 minutes would get extended every few page reloads because autoRegenerate is set to trueVerlaverlee
Sadly not, that just extends the PHP session expiration time and doesn't touch the cookie expiration time.Matrilineage
I think that whether or not the user was kicked out would depend on the requestCountdown setting. If it was 1 then after 20 minutes when they did a page refresh they would get a new session and would remain logged in indefinitely.Verlaverlee
Old thread but maybe somebody can answer: is 'autoRegenerate' => true a necessary prerequisite so that the session is extended or page load?Mcgruder
@MonkeyKing Auto-regenerate is necessary if you want to keep extending your session infinitely. Without it, the session will still expire after 24 hours (or whatever you set in cookieTimeout). Basically, without the autoRegenerate, you're extending the 30-minute PHP session up to the 1400-minute cookie timeout.Humanitarianism
Hi @all Does it possible to increase the session time in app controller or any other controller.Because i what to change session time dynamically in admin panel.using cake phpRheometer
'ini' => [ 'session.cookie_lifetime' => 60*12*5 //Cookie will be valid for 5days ], Use this for after cakephp 3.4 versions as cookieTimeout not working...Barman
A
8

While the timeout value resets on each pageview and hence provides the "inactivity timeout" you require, the browser's session cookie expiry date remains constant.

So while the Cake session would internally (internally = internal to Cake) still be alive if you refreshed on the 28th minute + 35th minute, the browser ends up deleting the session cookie after the 30th minute.

You can reset the session cookie expiry date via $this->Session->renew(). Or set autoRegenerate = true and requestCountdown = 1 and Cake will renew on each pageview.

(But it's kind of silly that you'd have to regenerate the session on every page view. As is, without renew(), the timeout value will never come into play because the cookie will always expire on a fixed date no matter how much activity. This seems like a bug but I haven't looked into a workaround.)

Annabelleannabergite answered 23/1, 2013 at 5:35 Comment(4)
Thanks, this made my day. I added the code to my AppController's beforeRender function; seems to work like a charm.Poirer
I have something in my app controller that resets the session cookie date time on each request using setcookie(). That did the trick for me but seems really hacky.Rennold
I've had trouble with requestCountdown = 1 and opening multiple tabs of the same web application. A few tabs down the line the request the new tab sends what is now an out of date cookie and is therefore logged out.Verlaverlee
This is what's called a "race condition". This will also occur if firing off multiple Ajax requests on the same page. The only solution is not to regenerate at every pageview (which is "good enough" for most -- unless your dealing with money). Just regenerate once every 10 pages -- your timeout minutes will be "fuzzy" but at least you won't get the error. If security is a huge concern, see security.stackexchange.com/questions/1246/…Annabelleannabergite
O
4

I had the same issue and I fixed it by using the autoRegenerate option:

Configure::write(
    'Session',
    array(
        'defaults' => 'cake',
        'timeout' => '30',
        'autoRegenerate' => true
    )
);

You could also use $this->Session->renew(); in your AppController.php class, but the above solution is my favourite.

Outside answered 23/1, 2013 at 4:3 Comment(3)
autoRegenerate only regenerate's the sessionid on every 10 (by default) pageviews. It does not have anything to do with time. It only counts down pageviews and is purely to mitigate session-stealing attacks. See: book.cakephp.org/2.0/en/development/sessions.htmlAnnabelleannabergite
So, I thought of this solution while I was scouring the interwebs for more details. My last attempt involved calling $this->Session->renew() in the beforeFilter method in the AppController. Unfortunately, this logs the user out every time they navigate to a new page. It seems renew clears session data for some strange reason.Receipt
I'm doing the same thing Kyle ($this->Session->renew() in the beforeFilter method in the AppController), and it seems to work running 2.4.1 stable.Poirer
L
2

the answer of Rob Forrest is the right one

Configure::write('Session', array(
        'defaults' => 'php',
        'timeout' => 30, // The session will timeout after 30 minutes of inactivity
        'cookieTimeout' => 1440
));

cookieTimeout should be larger than timeout if you want session to be expired on inactivity only then you need to set cookieTimeout for very large number (for example 60*24*10 (10 days ))

Loudish answered 6/4, 2014 at 7:51 Comment(1)
Agreed with the idea of setting cookieTimeout to far, far in the future. The session timeout is the only one that's extended on page load so without a far future cookieTimeout the cookie will eventually expire regardless of user activity.Verlaverlee
R
0
    Configure::write('Session', array(
    'defaults' => 'cake',
    'timeout' => 1440, // The session will timeout after 30 minutes of inactivity
    'cookieTimeout' => 1440, // The session cookie will live for at most 24 hours, this does not effect session timeouts
    'checkAgent' => false,
    'autoRegenerate' => true, // causes the session expiration time to reset on each page load
));

This works, though the session ends after few hours it is still better than ending in minutes.

Raposa answered 20/2, 2015 at 9:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.