When a session expiration time is defined, is it possible to call an event listener when it expires?
If it is not possible, is it possible to run a cron job to check if a session has expired?
NOTE: I'm interested in a server solution. I'm talking about the case there is a session expiration time defined, and the session finishes automatically because that period expired.
12 Answers
Answers 1
is it possible to call an event listener when it expires?
Short answer no.
There are a few oddities people tend to ignore about sessions. With the default handler, the session does not expire when gc_maxlifetime ends - this is just the time at which the data becomes eligible for automatic deletion. There is no action by the owner of the session which triggers the subsequent removal of the session - its a side effect of someone else's session.
When session_write_close() is called (either explicitly, or implicitly by the code ending), if the random number generator, tweaked by the relevant gc settings throws the right number then PHP will go looking for data past its TTL and remove it. If you want to trigger an action at this point, then you need to break the default handler and apply your own. That means you not only have to provide a mechanism for identifying and removing sessions but also a way of deciding whether your handler should kick in and how many sessions it should delete - you don't want a runaway process killing your server.
In Ubuntu, session.gc_probability = 0, and it is a cron job which carries out the function of removing stale data files.
A very important piece of information missing from your question is the reason for deleting the session.
If you want to prevent sensitive data from persisting on the filesystem, then a better solution is to encrypt the data using a key stored (only) in another client side cookie. That way you completely eliminate the storage of unprotected data on your server. (note that suhosin's encrypted sessions use a key derived from data about the client and a static key stored on the same host - this is significantly less secure than a randomly generated key). Here's one I prepared earlier.
If you merely want to prevent access after the gc_maxlifetime has expired, you should consider a custom session handler which treats a stale session as missing. i.e. it doesn't really logout at expiry, but any subsequent requests can no longer be associated with the seesion. The security layer in the Stackable session handler examples implements such a control.
OTOH if you want to use data from within the session in your event listener, then that's a different story - you certainly won't be able to use either Suhosin's or my encryption for the data. But a further complication is that the (default) format for the data is different from that used elsewhere. You need to use session_encode() and session_decode(). The former will only read data from the $_SESSION array so eavesdropping on sessions requires some careful subversion of session_id() and session_start(). session_decode() however will happily convert anything you throw at it.
In recent versions of PHP you can specify a different function pair to use for serialization/deserialization.
It is vitally important to consider the potential impact of __wakeup() methods when considering a session garbage collector which is going to read the data in the session files. Related to this is a requirement that the process which handles such garbage collection runs under the same uid as the original PHP process which created the session data (otherwise you have a privilege escalation backdoor). But if the session storage substrate is file-based then that would need to be the case anyway.
There are implementations of session data deserializer written in languages other than PHP which would provide protection against __wakeup() attacks (try Google) although that might be overkill to solve the problem and they are probably not being actively maintained. If this is a concern then a more appropriate solution might be to use the WDDX (xml) serializer and use a conventional XML parser to read the data back in your GC engine.
If you are using the native handler for normal reading and writing of the data but want to implement your own garbage collector then you're going to need code to map the session_id to a file path. If you follow the link I gave to PHPclasses above, you'll see pure PHP impleentation of several session handlers, including ones which are compatible with the native handler.
But I would strongly encourage you to exhaust every other avenue for solving whatever the underlying problem is before choosing to read back session data at the time of deletion.
Answers 2
It sounds like you want to wipe out the session at a given time on the server side. What you will want to do is define your own custom session handler and put the session data in a system you fully control. So, let's say you move your session handling into a database. Now all your session data is fully within your control. Below is an abbreviated custom session handler
class Sessions implements \SessionHandlerInterface { /** * Write Session Data * @param string $id Session ID to delete * @param string $data Data to write into the session */ public function write($id, $data) { $time = time() + 3600; // 1 hour for the sake of example $sql = 'REPLACE INTO your_session_table SET session_id = ?, data = ?, expires = ?'; $this->db->query($sql); $prep = $this->db->prepare($sql); $prep->bind_param('ssi', $id, $data, $time); $prep->execute(); } }
What you can do here is you can run your own cleanup script here. Now, I would suggest you use an intermediate memory store (memcached, Redis, etc) so you don't HAVE to load from the DB every time. You'll want to clean that out when you run your cleanup script (i.e pull all the sessions about to expire and remove from cache). But a simple SQL statement here (run on, say, a 5 minute cron job) cleans out sessions on demand
DELETE FROM your_session_table WHERE expires < now();
Answers 3
I'm making a couple of assumptions here.
I'm assuming, for whatever reason, you want to be able to track the expired session cold, that is, no supplementary tracking of session data via a database or a second 'hidden' session that acts as a structure to determine when a pseudo-session has expired and acting appropriately.
I'm also assuming that hack attempts on your session aren't important at this point. Man-in-the-middle and XSS attacks can capture session ID's and plug them into your system and it would be hard to detect.
This sort of thing is handled by session cookies in php by default. I'm also assuming that your session identification and session start are also handled by cookies.
There's almost no way of doing this 'live', which is to say, keep a socket open to the server to detect the moment the session expires. PHP was not designed to work that way; the security issues are expansive. As well, if you're allowing someone to access your server remotely through a secure channel, why are you bothering with sessions in the first place?
$sessionCookie = 'myPHPSessCookieName'; $isSessionExpired = false; if (isset($_COOKIE[$sessionCookie])) { // check cookie expiry time to show warnings / near expiry behaviours } else { // handle missing cookie / session $isSessionExpired = true; } define('SESSION_EXPIRED', $isSessionExpired); session_start(['name' => $sessionCookie]);
Checking for the cookie has to happen prior to starting the session otherwise you run the risk of giving yourself a false positive.
[edit: javascript solution]
If you wish to produce a behaviour that simulates a socket, javascript can do this. The client's browser will ping the server with AJAX requests to check the status of their session, and once it detects that it is expired, you can induce a behaviour of your choice. Note: javascript in its current state is fundamentally insecure. All of the data and security related work ought to be done by the server if at all possible.
client.php:
<script> $(function(){ var messageElem = $('#selectorForDisplayElementHere'); var timeoutID = null; var checkSession = function(){ $ .ajax({/* your ajax params: url, data, dataType, method etc. */}) .then(function(response){ messageElem.html(response.html); if (response.stop === 1) { clearTimeout(timeoutID); } }); }; var timeoutID = setInterval(checkSession, 5000); // Every 5 seconds }); </script>
ajax.php:
$response = ['html' => '', 'stop' => 0]; if (SESSION_EXPIRED) { $response ['html'] = '<b>Your session has expired. Please log in again.</b>'; $response['stop'] = 1; } echo(json_encode($response));
This is a very simple handling system that can be readily enhanced with all sorts of functionality. It uses the ubiquitous jQuery library and standard php and html/javascript functionality.
Answers 4
You could store the connection time somewhere (table,...) so you can see since when the user was connected and do a regular check (cron or service) to see if the date has passed a specific duration (5 minutes,...)
But if you want to warn the user (loss of document,...) you might want to do a Javascript window.setTimeout
on client side.
Answers 5
Set initial session on one page.
example: Login.php
<?php session_start(); if(...){ // success $_SESSION['logged_time'] = time(); } ?>
now check the session expired or not in another page
example: Index.php
<?php session_start(); $login_session_duration = 60; // 1 minute if($_SESSION['logged_time']){ if(((time() - $_SESSION['logged_time']) > $login_session_duration)){ echo 'session expired'; // session will be exired after 1 minutes }else{ echo 'session alive'; } } ?>
Answers 6
I think what you are looking for may be here: Access active sessions in PHP
Summarized you would have to create your own session handler. That's the server side.
If you want to add client side alerts you could store the session expiration time limit used in a javascript timer. If there is only x minutes left pop up a message (maybe with a countdown) displaying to the user "Your session will time out in: (show timer here)."
Answers 7
You can also use this :)
<? session_start(); $time = 3600; // Set expire time with secends. // Star session here if (isset($_SESSION['time']) && (time() - $_SESSION['time']) > $time) { // Your Code Here to logout header('location: /auth/logout'); exit(); } else { $_SESSION['time'] = time(); }
Answers 8
Each time you send http request to server then check the session expiration time. if session is valid do your stuff, other wise redirect where you want.
Or
You can do one thing to save your time. Create a method which checks current session validity and call it in your http request.
Answers 9
Well very simple way to do is
get current_time
$current_time=time();
get session expire time which is set in ini file.
$maxlifetime = ini_get("session.gc_maxlifetime");
Use this value in javascript/query and when time is expire by mannual calculation use a alert to notify user or write script u wish to do.
OR
You can store these dates in separate cookie variable:
session_expire=1525357483057
But user can change this variable.
Answers 10
Try checking it against session_cache_expire() if it is zero then your session has ended. Would probably have to be implemented on your action handler. This does not set your session on the server, only solves the problem of your clients browser knowing when it will expire, which is serving as your auto detect...
Answers 11
We can use the session variable that you have defined.
if(isset($_SESSION['variable'])){ //do something }
example:
if(isset($_SESSION['name'])){ echo "Session has not expired"; }
Answers 12
What you would do is run a jQuery AJAX request on a timed interval to check if the session is expired and when it does you can send the users to a logout.
Ajax Code
var checkSession; function SessionCheck(){ var str="sessionCheck=true"; jQuery.ajax({ type:"POST", URL:"sessionCheck.php" data: str, success: function(res){ if(res==1){ //do session expired logic here } } }); } sessions = setInterval(SessionCheck, 1000); //This will run the SessionCheck function every second
PHP Code
session_start(); $data = $_SESSION["sessionVariable"]; if($data == ''){ echo "1"; } else{ echo "0"; }
0 comments:
Post a Comment