I have a very basic php session login script. I want to force logout of a certain user or force logout of all users.
How can I read all sessions made to my website, and destroy some or all sessions?
I have a very basic php session login script. I want to force logout of a certain user or force logout of all users.
How can I read all sessions made to my website, and destroy some or all sessions?
You could try to force PHP to delete all the sessions by doing
ini_set('session.gc_max_lifetime', 0);
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);
That forces PHP to treat all sessions as having a 0-second lifetime, and a 100% probability of getting cleaned up.
The drawback is that whichever unlucky user runs this first will get a long pause while PHP does cleanup, especially if there's a lot of session files to go through.
For one particular user, you'd have to add some code to your session handler:
if ($_SESSION['username'] == 'user to delete') {
session_destroy();
}
PHP's garbage collector isn't controllable, so you can't give it parameters such as "delete all sessions except for user X's". It looks strictly at the last-modified/last-accessed timestamps on the session files and compares that to the max_lifetime setting. It doesn't actually process the session data.
You can use session_save_path()
to find the path where PHP saves the session files, and then delete them using unlink()
.
This code is based from the official PHP site, and another well written snippet on SO.
<?php
// Finds all server sessions
session_start();
// Stores in Array
$_SESSION = array();
// Swipe via memory
if (ini_get("session.use_cookies")) {
// Prepare and swipe cookies
$params = session_get_cookie_params();
// clear cookies and sessions
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
// Just in case.. swipe these values too
ini_set('session.gc_max_lifetime', 0);
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);
// Completely destroy our server sessions..
session_destroy();
?>
Works well. Servers like NGinx you can turn off, clean cache, swipe memory reset, clear logs etc and generally remove temp usage. Even drop the limits of memory.
It depends on your session storage.
If you're using PHP session storage, then they may be in the temporary directory of your server. Deleting the selected files will "kill" the session. However if your server is in running state, that session file may be occupied by HTTP process and you won't be able to delete it. Just look at the image below. File named as starting with "+~" are all session files.
A nicer solution is to use a database session storage and delete the selected sessions from there. You can check out HTTP_Session2
which has multiple containers.
Clearling all sessions at once would require first knowing which session.save_handler
is being used to store sessions and locating the session.save_path
in order to delete all sessions. For deleting the current session only, refer to the documentation for session_destroy()
.
Here are some common examples for deleting all sessions using standard file and memcached save handlers:
foreach(glob(ini_get("session.save_path") . "/*") as $sessionFile) {
unlink($sessionFile);
}
$memcached = new Memcached;
$memcached->addServers($listOfYourMemcachedSesssionServers);
// Memcached session keys are prefixed with "memc.sess.key." by default
$sessionKeys = preg_grep("@^memc\.sess\.key\.@", $memcached->getAllKeys());
$memcached->deleteMulti($sessionKeys);
Of course, you might want to consider only doing this out of band from your normal HTTP client requests, since cleaning up large session storage may take some time and have inadvertent side effects in a normal request life cycle.
I found this code very helpful and it really worked for me
<?php
$path = session_save_path();
$files = glob($path.'/*'); // get all file names
foreach($files as $file){ // iterate files
if(is_file($file))
unlink($file); // delete file
}
?>
I will create a txt
file containing the token which has the same value as the generated login session as a comparison every time the user is logged in:
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$token = sha1(uniqid(mt_rand(), true));
if($everything_is_valid) {
// Set login session
$_SESSION[$_POST['username']] = $token;
// Create token file
file_put_contents('log/token.' . $_POST['username'] . '.txt', $token);
// Just to be safe
chmod('log/token.' . $_POST['username'] . '.txt', 0600);
}
}
Checks for logged in user(s):
if(isset($_SESSION['charlie']) && file_exists('log/token.charlie.txt') && $_SESSION['charlie'] == file_get_contents('log/token.charlie.txt')) {
echo 'You are logged in.';
}
So, if you want to force this charlie
user to be logged out, simply remove the token file:
// Force logout the `charlie` user
unlink('log/token.charlie.txt');
Taufik's answer is the best i could find.
However, you can further modify it
After authenticating the user and creating the session variables, add these lines:
$token = "/sess_" . session_id();
file_put_contents('log/' . $_SESSION['id'] . '.txt', $token);
If you need to force the user to log out during a cronjob or by an admin request:
$path = session_save_path();
$file = file_get_contents('log/xxx.txt'); // xxx is user's id
$url = $path.$file;
unlink($url);
remove all session variables
session_unset();
destroy the session
session_destroy();