How to Set Lifetime of Session

How to set lifetime of session

The sessions on PHP works with a Cookie type session, while on server-side the session information is constantly deleted.

For set the time life in php, you can use the function session_set_cookie_params, before the session_start:

session_set_cookie_params(3600,"/");
session_start();

For ex, 3600 seconds is one hour, for 2 hours 3600*2 = 7200.

But it is session cookie, the browser can expire it by itself, if you want to save large time sessions (like remember login), you need to save the data in the server and a standard cookie in the client side.

You can have a Table "Sessions":

  • session_id int
  • session_hash varchar(20)
  • session_data text

And validating a Cookie, you save the "session id" and the "hash" (for security) on client side, and you can save the session's data on the server side, ex:

On login:

setcookie('sessid', $sessionid, 604800);      // One week or seven days
setcookie('sesshash', $sessionhash, 604800); // One week or seven days
// And save the session data:
saveSessionData($sessionid, $sessionhash, serialize($_SESSION)); // saveSessionData is your function

If the user return:

if (isset($_COOKIE['sessid'])) {
if (valide_session($_COOKIE['sessid'], $_COOKIE['sesshash'])) {
$_SESSION = unserialize(get_session_data($_COOKIE['sessid']));
} else {
// Dont validate the hash, possible session falsification
}
}

Obviously, save all session/cookies calls, before sending data.

How do I expire a PHP session after 30 minutes?

You should implement a session timeout of your own. Both options mentioned by others (session.gc_maxlifetime and session.cookie_lifetime) are not reliable. I'll explain the reasons for that.

First:

session.gc_maxlifetime
session.gc_maxlifetime specifies the number of seconds after which data will be seen as 'garbage' and cleaned up. Garbage collection occurs during session start.

But the garbage collector is only started with a probability of session.gc_probability divided by session.gc_divisor. And using the default values for those options (1 and 100 respectively), the chance is only at 1%.

Well, you could simply adjust these values so that the garbage collector is started more often. But when the garbage collector is started, it will check the validity for every registered session. And that is cost-intensive.

Furthermore, when using PHP's default session.save_handler files, the session data is stored in files in a path specified in session.save_path. With that session handler, the age of the session data is calculated on the file's last modification date and not the last access date:

Note: If you are using the default file-based session handler, your filesystem must keep track of access times (atime). Windows FAT does not so you will have to come up with another way to handle garbage collecting your session if you are stuck with a FAT filesystem or any other filesystem where atime tracking is not available. Since PHP 4.2.3 it has used mtime (modified date) instead of atime. So, you won't have problems with filesystems where atime tracking is not available.

So it additionally might occur that a session data file is deleted while the session itself is still considered as valid because the session data was not updated recently.

And second:

session.cookie_lifetime
session.cookie_lifetime specifies the lifetime of the cookie in seconds which is sent to the browser. […]

Yes, that's right. This only affects the cookie lifetime and the session itself may still be valid. But it's the server's task to invalidate a session, not the client. So this doesn't help anything. In fact, having session.cookie_lifetime set to 0 would make the session’s cookie a real session cookie that is only valid until the browser is closed.

Conclusion / best solution:

The best solution is to implement a session timeout of your own. Use a simple time stamp that denotes the time of the last activity (i.e. request) and update it with every request:

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
// last request was more than 30 minutes ago
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp

Updating the session data with every request also changes the session file's modification date so that the session is not removed by the garbage collector prematurely.

You can also use an additional time stamp to regenerate the session ID periodically to avoid attacks on sessions like session fixation:

if (!isset($_SESSION['CREATED'])) {
$_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
// session started more than 30 minutes ago
session_regenerate_id(true); // change session ID for the current session and invalidate old session ID
$_SESSION['CREATED'] = time(); // update creation time
}

Notes:

  • session.gc_maxlifetime should be at least equal to the lifetime of this custom expiration handler (1800 in this example);
  • if you want to expire the session after 30 minutes of activity instead of after 30 minutes since start, you'll also need to use setcookie with an expire of time()+60*30 to keep the session cookie active.

How to change the session timeout in PHP?

Session timeout is a notion that has to be implemented in code if you want strict guarantees; that's the only way you can be absolutely certain that no session ever will survive after X minutes of inactivity.

If relaxing this requirement a little is acceptable and you are fine with placing a lower bound instead of a strict limit to the duration, you can do so easily and without writing custom logic.

Convenience in relaxed environments: how and why

If your sessions are implemented with cookies (which they probably are), and if the clients are not malicious, you can set an upper bound on the session duration by tweaking certain parameters. If you are using PHP's default session handling with cookies, setting session.gc_maxlifetime along with session_set_cookie_params should work for you like this:

// server should keep session data for AT LEAST 1 hour
ini_set('session.gc_maxlifetime', 3600);

// each client should remember their session id for EXACTLY 1 hour
session_set_cookie_params(3600);

session_start(); // ready to go!

This works by configuring the server to keep session data around for at least one hour of inactivity and instructing your clients that they should "forget" their session id after the same time span. Both of these steps are required to achieve the expected result.

  • If you don't tell the clients to forget their session id after an hour (or if the clients are malicious and choose to ignore your instructions) they will keep using the same session id and its effective duration will be non-deterministic. That is because sessions whose lifetime has expired on the server side are not garbage-collected immediately but only whenever the session GC kicks in.

    GC is a potentially expensive process, so typically the probability is rather small or even zero (a website getting huge numbers of hits will probably forgo probabilistic GC entirely and schedule it to happen in the background every X minutes). In both cases (assuming non-cooperating clients) the lower bound for effective session lifetimes will be session.gc_maxlifetime, but the upper bound will be unpredictable.

  • If you don't set session.gc_maxlifetime to the same time span then the server might discard idle session data earlier than that; in this case, a client that still remembers their session id will present it but the server will find no data associated with that session, effectively behaving as if the session had just started.

Certainty in critical environments

You can make things completely controllable by using custom logic to also place an upper bound on session inactivity; together with the lower bound from above this results in a strict setting.

Do this by saving the upper bound together with the rest of the session data:

session_start(); // ready to go!

$now = time();
if (isset($_SESSION['discard_after']) && $now > $_SESSION['discard_after']) {
// this session has worn out its welcome; kill it and start a brand new one
session_unset();
session_destroy();
session_start();
}

// either new or old, it should live at most for another hour
$_SESSION['discard_after'] = $now + 3600;

Session id persistence

So far we have not been concerned at all with the exact values of each session id, only with the requirement that the data should exist as long as we need them to. Be aware that in the (unlikely) case that session ids matter to you, care must be taken to regenerate them with session_regenerate_id when required.

What is the default lifetime of a session?

Check out php.ini the value set for session.gc_maxlifetime is the ID lifetime in seconds.

I believe the default is 1440 seconds (24 mins)

http://www.php.net/manual/en/session.configuration.php

Edit: As some comments point out, the above is not entirely accurate. A wonderful explanation of why, and how to implement session lifetimes is available here:

How do I expire a PHP session after 30 minutes?

Laravel session expire time for each session

You can change the session lifetime, application wide by changing the lifetime value on config/session.php:

/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/

'lifetime' => 4320,
'expire_on_close' => false,

Now, if you want to control the session lifetime per user, you need to set this value before logging in the user.

  1. Try if user exists in database
  2. If yes, and he is user who needs longer session lifetime, run config(['session.lifetime' => $newLifetime]);
  3. Log user in
  4. Enjoy longer session lifetime for current user

— Source

You have to make the above changes in LoginController.



Related Topics



Leave a reply



Submit