Подтвердить что ты не робот

Как убить все/php-сессии?

У меня есть очень простой php сеанс login script. Я хочу принудительно выйти из системы для определенного пользователя или выйти из системы всех пользователей.

Как я могу прочитать все сеансы, сделанные на моем веб-сайте, и уничтожить некоторые или все сеансы?

4b9b3361

Ответ 1

Вы можете попытаться заставить PHP удалить все сеансы, выполнив

ini_set('session.gc_max_lifetime', 0);
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);

Это заставляет PHP обрабатывать все сеансы как имеющие 0-секундное время жизни и 100% вероятность очистки.

Недостатком является то, что какой бы неудачный пользователь этого не выполнил, он получит длинную паузу, пока PHP делает очистку, особенно если есть много файлов сеансов, которые нужно пройти.

Для одного конкретного пользователя вам нужно добавить код к обработчику сеанса:

 if ($_SESSION['username'] == 'user to delete') {
     session_destroy();
 }

Сборщик мусора PHP не контролируется, поэтому вы не можете дать ему такие параметры, как "удалить все сеансы, кроме пользователя X". Он строго смотрит на временные метки последнего изменения/последнего доступа в файлах сеансов и сравнивает их с параметром max_lifetime. Он фактически не обрабатывает данные сеанса.

Ответ 2

Обновлено - август 2012

Этот код основан на официальном сайте PHP, а другой хорошо написанный фрагмент на 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();
?>

Хорошо работает. Серверы, такие как NGinx, вы можете отключить, очистить кеш, проведите память reset, очистить журналы и т.д. И вообще удалить временное использование. Даже сбросьте пределы памяти.

Ответ 3

Вы можете использовать session_save_path() чтобы найти путь, где PHP сохраняет файлы сессий, а затем удалить их с помощью unlink().

Ответ 4

Это зависит от вашей сессии хранения.

Если вы используете хранилище сессий PHP, то они могут находиться во временном каталоге вашего сервера. Удаление выбранных файлов "убьет" сеанс. Однако, если ваш сервер находится в рабочем состоянии, этот файл сеанса может быть занят процессом HTTP, и вы не сможете его удалить. Просто посмотрите на изображение ниже. Все файлы с именами, начинающимися с "+ ~". Screenshot of Session Occupied by Process and could not delete it

Более удачным решением является использование хранилища сеансов базы данных и удаление оттуда выбранных сеансов. Вы можете проверить HTTP_Session2 который имеет несколько контейнеров.

Ответ 5

Я создам файл txt, содержащий токен, который имеет такое же значение, что и сгенерированный сеанс входа в систему, для сравнения каждый раз, когда пользователь регистрируется:

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);
    }
}

Проверяет для зарегистрированных пользователей:

if(isset($_SESSION['charlie']) && file_exists('log/token.charlie.txt') && $_SESSION['charlie'] == file_get_contents('log/token.charlie.txt')) {
    echo 'You are logged in.';
}

Итак, если вы хотите заставить этого пользователя charlie выйти из системы, просто удалите файл токена:

// Force logout the `charlie` user
unlink('log/token.charlie.txt');

Ответ 6

Сброс всех сеансов сразу потребует сначала знать, что session.save_handler используется для хранения сеансов и располагая session.save_path, чтобы удалить все сеансы. Для удаления только текущего сеанса обратитесь к документации для session_destroy().

Вот несколько распространенных примеров для удаления всех сеансов с использованием стандартных файлов и обработчиков сохранения memcached:

Использование обработчика сохранения файлов

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

Использование обработчика сохранения memcached

$memcached = new Memcached;
$memcached->addServers($listOfYourMemcachedSesssionServers);

// Memcached session keys are prefixed with "memc.sess.key." by default
$sessionKeys = preg_grep("@^memc\.sess\.key\[email protected]", $memcached->getAllKeys());
$memcached->deleteMulti($sessionKeys);

Конечно, вам может потребоваться рассмотреть возможность выполнения этого вне диапазона из ваших обычных запросов HTTP-клиентов, так как очистка большого хранилища сеансов может занять некоторое время и иметь непреднамеренные побочные эффекты в нормальном жизненном цикле запроса.

Ответ 7

Я нашел этот код очень полезным, и это действительно сработало для меня.

<?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
}

?>

Ответ 8

Ответ Taufik - лучшее, что я мог найти.
Однако вы можете дополнительно изменить его
После аутентификации пользователя и создания переменных сеанса добавьте следующие строки:

$token = "/sess_" . session_id();
file_put_contents('log/' . $_SESSION['id'] . '.txt', $token);

Если вам нужно заставить пользователя выйти из системы во время cronjob или по запросу администратора:

$path = session_save_path();
$file = file_get_contents('log/xxx.txt'); // xxx is user id
$url = $path.$file;
unlink($url);