PHP Session Timeout Callback

How to deal with a PHP session timeout

JavaScript code:

$.ajax("populate_timesheets.php?start=" + TimesheetOffset, {
type: "GET",
statusCode: {
401: function (response) {
// redirect to login page
}
},
success: function (data) {
$( "#timesheets" ).html(data);
},
error: function (error) {
console.log('Error occured: ', error);
}
});

PHP code:

if (!isset($_SESSION['login_user'])) {
header("HTTP/1.1 401 Unauthorized");
return;
}

I don't test this code, so if you have problem, read jQuery documentation about AJAX Requests :)

Perform some event when php session timeout

There's no way to catch the on browser close event in JavaScript. You can try web socket and CRON job to achieve your wants.

For web socket, you can get the total connections of specific user, and if the connection becomes 0, it means that the user closed all the pages(window or tab) of your web app. Also, you need to keep in your mind the internet disconnection, by this, you need to use CRON job, this CRON job must run every specific minutes (ex: 15 mins), so that if the user lost a connection for 15 minutes, you must automatically log out that user.

If you don't have rules like user must be disconnected after several minutes of idling, then you can just simply use web socket.

PHP Session expire event

I did something really nasty once. Every time a session was "updated" by a page refresh / fetch / etc., I updated a timestamp on a DB row. A second daemon polled the DB every 10 minutes and performed "clean-up" operations.

You won't find any native PHP facilities to achieve your goal. Session timeout doesn't run in the background. You won't even know if a session is timed out, unless a timed out session attempts another access. At this point, nearly impossible to trap, you can make your determination and handle it appropriately.

I'd recommend a queue & poll architecture for this problem. It's easy and will definitely work. Add memcached if you have concerns about transaction performance.

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.

PHP Session Expiration

If you need to call specific expiration logic (for example, in order to update a database) and want independence from requests then it would make sense to implement an external session handler daemon that looks at access times of session files. The daemon script should execute whatever necessary for every session file that has not been accessed for a specified time.

This solution has two prerequisites: the server's filesystem supports access times (Windows does not) and you can read files from session save path.



Related Topics



Leave a reply



Submit