Как убить все/php-сессии?
У меня есть очень простой php сеанс login script. Я хочу принудительно выйти из системы для определенного пользователя или выйти из системы всех пользователей.
Как я могу прочитать все сеансы, сделанные на моем веб-сайте, и уничтожить некоторые или все сеансы?
Ответы
Ответ 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);