34

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?

TDSii
  • 1,675
  • 4
  • 20
  • 29
  • 7
    Please consider accepting one of the provided answers to reward the people that have taken the time out their day to help you. If several answers have helped you, you can upvote them too. – conradkleinespel Jan 27 '16 at 11:58

9 Answers9

21

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.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • 2
    to remove a session in your second code is only locally. $_SESSION variable is independent of each user, my aim is to be able to have all sessions for all users to destroy who ever is logged in – TDSii Mar 04 '11 at 18:07
  • 2
    yes, but you said you wanted to log out one, or all, users. The ini-set stuff takes care of everyone. the if() takes care of a particular user. – Marc B Mar 04 '11 at 18:57
  • Does it not work in recent versions? I'm using wampserver 2.5 with apache 2.4.9 and php 5.5.x. This delete not even one sess_* files stored at the tmp directory at all, except only session_destroy() delete the current session's file. – Johnny Wong Oct 30 '15 at 21:48
11

You can use session_save_path() to find the path where PHP saves the session files, and then delete them using unlink().

HaskellElephant
  • 9,819
  • 4
  • 38
  • 67
m4rc
  • 2,932
  • 2
  • 22
  • 29
  • 4
    Be very careful with this approach if the path in question turns out to be the global /tmp directory! There's bound to be other processes other than PHP storing temporary data there. If PHP has its own directory set aside for session data it should be fairly safe though. – GordonM Mar 04 '11 at 12:38
  • 2
    Obviously this isn't a good practice - but I'm just giving the man what he wants! :-p – m4rc Mar 04 '11 at 13:02
  • 2
    This is the best answer for what OP asked, except it does not address systems where Session is not stored on the file system (eg in the database as KARASZI István mentioned). – Mr Griever Oct 10 '13 at 20:40
  • 3
    Note, this will log all users out of all accounts on the server. If you have multiple domains on the one server and you delete the session files with root privileges, you'll be logging out all users on all domains. – cronoklee May 23 '19 at 12:01
7

Updated - Aug 2012

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.

Community
  • 1
  • 1
TheBlackBenzKid
  • 26,324
  • 41
  • 139
  • 209
6

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. Screenshot of Session Occupied by Process and could not delete it

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.

Kiran Maniya
  • 8,453
  • 9
  • 58
  • 81
KARASZI István
  • 30,900
  • 8
  • 101
  • 128
  • 1
    any build-in methods, what does webmasters usually use? – TDSii Mar 04 '11 at 13:09
  • You mean PHP session storage? – Marc B Mar 04 '11 at 14:28
  • @MarcB Session storage means the session data of the specific user will be stored somewhere. by default PHP Session stores in the temp directory of OS. in windows session will be stored in C:\Users\USER_NAME\AppData\Local\Temp. You can allso override default mechanism and store session in database which will give you more control over session. – Kiran Maniya Jun 08 '19 at 06:16
5

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:

Using file save handler

foreach(glob(ini_get("session.save_path") . "/*") as $sessionFile) {
    unlink($sessionFile);
}

Using memcached save handler

$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.

Sherif
  • 11,786
  • 3
  • 32
  • 57
  • 1
    This is dangerous code. Should ini_get return "" (which it does in many circumstances) the array will equal to all directories under root, and attempt to delete them. – Guillermo Apr 03 '23 at 08:17
4

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
}

?>
  • 5
    Dangerous! You need to check that they are php session files and that the belong to your user before deleting them. There could be tonnes of other files in that save path – cronoklee May 23 '19 at 12:03
2

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 Nurrohman
  • 3,329
  • 24
  • 39
2

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);
nu everest
  • 9,589
  • 12
  • 71
  • 90
Robin LeBon
  • 150
  • 11
1

remove all session variables

session_unset();

destroy the session

session_destroy();
Tehleel Mir
  • 743
  • 8
  • 27