J'ai un script de connexion de session php très basique. Je veux forcer la déconnexion d'un certain utilisateur ou forcer la déconnexion de tous les utilisateurs.
Comment puis-je lire toutes les sessions effectuées sur mon site Web et détruire certaines ou toutes les sessions?
Vous pouvez essayer de forcer PHP pour supprimer toutes les sessions en faisant
ini_set('session.gc_max_lifetime', 0);
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);
Cela oblige PHP à traiter toutes les sessions comme ayant une durée de vie de 0 seconde et une probabilité de 100% de se nettoyer.
L'inconvénient est que, quel que soit l'utilisateur malchanceux qui exécute cette première, il y aura une longue pause pendant que PHP fait le nettoyage, surtout s'il y a beaucoup de fichiers de session à parcourir.
Pour un utilisateur particulier, vous devez ajouter du code à votre gestionnaire de session:
if ($_SESSION['username'] == 'user to delete') {
session_destroy();
}
Le garbage collector de PHP n'est pas contrôlable, vous ne pouvez donc pas lui donner des paramètres tels que "supprimer toutes les sessions sauf celles de l'utilisateur X". Il examine strictement les horodatages modifiés en dernier/dernier accès sur les fichiers de session et les compare au paramètre max_lifetime. Il ne traite pas réellement les données de session.
Vous pouvez utiliser session_save_path()
pour trouver le chemin où PHP enregistre les fichiers de session, puis les supprimer à l'aide de unlink()
.
Ce code est basé sur le officiel PHP , et un autre bien écrit extrait sur 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();
?>
Fonctionne bien. Des serveurs comme NGinx vous pouvez désactiver, nettoyer le cache, réinitialiser la mémoire, effacer les journaux, etc. et généralement supprimer l'utilisation temporaire. Laissez tomber même les limites de la mémoire.
Cela dépend du stockage de votre session.
Si vous utilisez PHP stockage de session, ils peuvent se trouver dans le répertoire temporaire de votre serveur. La suppression des fichiers sélectionnés "tuera" la session. Cependant, si votre serveur est en cours d'exécution, ce fichier de session peut être occupé par le processus HTTP et vous ne pourrez pas le supprimer. Regardez simplement l'image ci-dessous. Le fichier nommé en commençant par "+ ~" sont tous des fichiers de session.
Une meilleure solution consiste à utiliser un stockage de session de base de données et à supprimer les sessions sélectionnées à partir de là. Vous pouvez vérifier HTTP_Session2
qui a plusieurs conteneurs .
Pour effacer toutes les sessions à la fois, il faudrait d'abord savoir laquelle session.save_handler
est utilisée pour stocker les sessions et localiser le session.save_path
pour supprimer toutes les sessions. Pour supprimer la session en cours uniquement, reportez-vous à la documentation de session_destroy()
.
Voici quelques exemples courants de suppression de toutes les sessions à l'aide de fichiers standard et de gestionnaires de sauvegarde memcached:
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);
Bien sûr, vous voudrez peut-être envisager de ne le faire que hors bande à partir de vos demandes client HTTP normales, car le nettoyage du stockage de grandes sessions peut prendre un certain temps et avoir des effets secondaires par inadvertance dans un cycle de vie de demande normal.
Je vais créer un fichier txt
contenant le jeton qui a la même valeur que la session de connexion générée à titre de comparaison chaque fois que l'utilisateur est connecté:
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);
}
}
Vérifie les utilisateurs connecté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.';
}
Donc, si vous souhaitez forcer la déconnexion de cet utilisateur charlie
, supprimez simplement le fichier de jeton:
// Force logout the `charlie` user
unlink('log/token.charlie.txt');
J'ai trouvé ce code très utile et cela a vraiment fonctionné pour moi
<?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
}
?>
La réponse de Taufik est la meilleure que j'ai pu trouver.
Cependant, vous pouvez encore le modifier
Après avoir authentifié l'utilisateur et créé les variables de session, ajoutez ces lignes:
$token = "/sess_" . session_id();
file_put_contents('log/' . $_SESSION['id'] . '.txt', $token);
Si vous devez forcer l'utilisateur à se déconnecter lors d'un cronjob ou par une demande d'administrateur:
$path = session_save_path();
$file = file_get_contents('log/xxx.txt'); // xxx is user's id
$url = $path.$file;
unlink($url);