【问题标题】:How to kill a/all php sessions?如何杀死一个/所有的 php 会话?
【发布时间】:2011-07-08 19:15:02
【问题描述】:

我有一个非常基本的 php 会话登录脚本。我想强制注销某个用户或强制注销所有用户。

我如何才能读取对我的网站进行的所有会话,并销毁部分或所有会话?

【问题讨论】:

  • 请考虑接受提供的答案之一,以奖励那些抽出时间帮助您的人。如果几个答案对您有所帮助,您也可以投票。

标签: php session login


【解决方案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 设置进行比较。它实际上并不处理会话数据。

【讨论】:

  • 仅在本地删除第二个代码中的会话。 $_SESSION 变量独立于每个用户,我的目标是能够为所有用户创建所有会话以销毁曾经登录过的用户
  • 是的,但您说您想注销一个或所有用户。 ini-set 的东西照顾每个人。 if() 处理特定用户。
  • 最近的版本不能用吗?我将 wampserver 2.5 与 apache 2.4.9 和 php 5.5.x 一起使用。这甚至不会删除存储在 tmp 目录中的一个 sess_* 文件,除了 session_destroy() 删除当前会话的文件。
【解决方案2】:

您可以使用session_save_path() 找到PHP 保存会话文件的路径,然后使用unlink() 删除它们。

【讨论】:

  • 如果有问题的路径是全局 /tmp 目录,请务必小心使用此方法!除了 PHP 之外,肯定还有其他进程在那里存储临时数据。如果 PHP 为会话数据预留了自己的目录,那么它应该是相当安全的。
  • 显然这不是一个好习惯——但我只是给了那个人他想要的东西! :-p
  • 这是 OP 要求的最佳答案,除了它没有解决 Session 未存储在文件系统上的系统(例如,在 KARASZI István 提到的数据库中)。
  • 注意,这会将所有用户从服务器上的所有帐户中注销。如果您在一台服务器上有多个域,并且使用 root 权限删除会话文件,您将注销所有域上的所有用户。
【解决方案3】:

更新 - 2012 年 8 月

这段代码基于official PHP site,另一个写得很好的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();
?>

效果很好。像 NGinx 这样的服务器,您可以关闭、清理缓存、刷卡内存重置、清除日志等,并且通常会删除临时使用。甚至打破内存的限制。

【讨论】:

  • @GeorgeGarchagudashvili 你遇到什么问题?
  • 这只会杀死当前会话,我正在使用共享托管,所以我没有太多访问权限。如果有的话,我想杀死所有当前的 authed 会话
【解决方案4】:

一次清除所有会话需要首先知道哪个session.save_handler被用于存储会话并找到session.save_path以删除所有会话。仅删除当前会话,请参考the documentation for 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\.@", $memcached->getAllKeys());
$memcached->deleteMulti($sessionKeys);

当然,您可能只想考虑只在正常 HTTP 客户端请求的带外执行此操作,因为清理大型会话存储可能需要一些时间,并且在正常的请求生命周期中会产生无意的副作用。

【讨论】:

    【解决方案5】:

    这取决于您的会话存储。

    如果您使用的是 PHP 会话存储,那么它们可能位于您服务器的临时目录中。删除选定的文件将“终止”会话。但是,如果您的服务器处于运行状态,则该会话文件可能已被 HTTP 进程占用,您将无法删除它。看看下面的图片。以“+~”开头的文件都是会话文件。

    更好的解决方案是使用数据库会话存储并从那里删除选定的会话。您可以查看HTTP_Session2,它有多个containers

    【讨论】:

    • 任何内置方法,站长一般都用什么?
    • 你的意思是 PHP 会话存储?
    • @MarcB 会话存储意味着特定用户的会话数据将存储在某个地方。默认情况下,PHP Session 存储在 OS 的 temp 目录中。在 windows 会话中将存储在 C:\Users\USER_NAME\AppData\Local\Temp 中。您也可以覆盖默认机制并将会话存储在数据库中,这将使您能够更好地控制会话。
    【解决方案6】:

    我发现这段代码非常有用,它真的对我有用

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

    【讨论】:

    • 危险!在删除它们之前,您需要检查它们是否是 php 会话文件并且属于您的用户。该保存路径中可能有大量其他文件
    【解决方案7】:

    我将创建一个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');
    

    【讨论】:

      【解决方案8】:

      陶菲克的答案是我能找到的最好的答案。
      但是,您可以进一步修改它
      验证用户并创建会话变量后,添加以下行:

      $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's id
      $url = $path.$file;
      unlink($url);
      

      【讨论】:

        【解决方案9】:

        删除所有会话变量

        session_unset();
        

        销毁会话

        session_destroy();
        

        【讨论】:

          猜你喜欢
          • 2011-08-11
          • 1970-01-01
          • 1970-01-01
          • 2013-01-05
          • 1970-01-01
          • 2016-06-21
          • 1970-01-01
          • 1970-01-01
          • 2012-03-16
          相关资源
          最近更新 更多