web-dev-qa-db-fra.com

PHP: comment détecter si une session a expiré automatiquement?

Lorsqu'une heure d'expiration de session est définie, est-il possible d'appeler un écouteur d'événements lorsqu'il expire?

Si ce n'est pas possible, est-il possible d'exécuter un travail cron pour vérifier si une session a expiré?

NOTE: Je suis intéressé par une solution de serveur. Je parle du cas où un délai d'expiration de session est défini, et la session se termine automatiquement car cette période a expiré.

12
ziiweb

Je fais quelques hypothèses ici.

Je suppose que, quelle que soit la raison, vous souhaitez pouvoir suivre la session expirée à froid, c'est-à-dire aucun suivi supplémentaire des données de session via une base de données ou une seconde session "masquée" servant de structure pour déterminer le moment où un pseudo -session a expiré et agi de manière appropriée.

Je suppose également que les tentatives de piratage de votre session ne sont pas importantes pour le moment. Les attaques man-in-the-middle et XSS peuvent capturer des identifiants de session et les brancher sur votre système, ce qui serait difficile à détecter.

Ce type de problème est géré par défaut par les cookies de session en php. Je suppose également que votre identification et votre début de session sont également gérés par des cookies.

Il n’ya pratiquement aucun moyen de faire cela en direct, c’est-à-dire de laisser un socket ouvert au serveur pour détecter le moment où la session expire. PHP n'a pas été conçu pour fonctionner de cette façon; les problèmes de sécurité sont vastes. De même, si vous autorisez une personne à accéder à votre serveur à distance via un canal sécurisé, pourquoi vous embêtez-vous avec les sessions?

$sessionCookie = 'myPHPSessCookieName';
$isSessionExpired = false;

if (isset($_COOKIE[$sessionCookie])) {
  // check cookie expiry time to show warnings / near expiry behaviours
} else {
  // handle missing cookie / session
  $isSessionExpired = true;
}

define('SESSION_EXPIRED', $isSessionExpired);    
session_start(['name' => $sessionCookie]);

La vérification du cookie doit avoir lieu avant le début de la session, sinon vous courez le risque de vous donner un faux positif.

[edit: solution javascript]

Si vous souhaitez produire un comportement qui simule une socket, javascript peut le faire. Le navigateur du client envoie une requête ping au serveur avec AJAX demandes de vérifier l'état de leur session. Une fois qu'il a détecté son expiration, vous pouvez induire un comportement de votre choix. Remarque: javascript dans son état actuel est fondamentalement non sécurisé. Toutes les tâches liées aux données et à la sécurité doivent être effectuées par le serveur, dans la mesure du possible.

client.php:

<script>
  $(function(){
    var messageElem = $('#selectorForDisplayElementHere');
    var timeoutID = null;

    var checkSession = function(){
      $
        .ajax({/* your ajax params: url, data, dataType, method etc. */})
        .then(function(response){
          messageElem.html(response.html);
          if (response.stop === 1) { 
            clearTimeout(timeoutID);
          }
        });
    };

    var timeoutID = setInterval(checkSession, 5000); // Every 5 seconds
  });
</script>

ajax.php:

$response = ['html' => '', 'stop' => 0];

if (SESSION_EXPIRED) {
  $response ['html'] = '<b>Your session has expired. Please log in again.</b>';
  $response['stop'] = 1;
}

echo(json_encode($response));

C'est un système de manipulation très simple qui peut être facilement amélioré avec toutes sortes de fonctionnalités. Il utilise la bibliothèque jQuery omniprésente et les fonctionnalités standard php et html/javascript.

3
Malovich

Il semble que vous souhaitiez effacer la session à un moment donné côté serveur. Ce que vous voudrez faire est de définir votre propre gestionnaire de session personnalisé et de placer les données de session dans un système que vous contrôlez complètement. Alors, disons que vous déplacez votre traitement de session dans une base de données. Maintenant, toutes vos données de session sont entièrement sous votre contrôle. Ci-dessous se trouve un abrégé gestionnaire de session personnalisé

class Sessions implements \SessionHandlerInterface {
    /**
     * Write Session Data
     * @param string $id Session ID to delete
     * @param string $data Data to write into the session
     */
    public function write($id, $data) {
        $time = time() + 3600; // 1 hour for the sake of example
        $sql = 'REPLACE INTO your_session_table
                SET session_id = ?,
                    data = ?,
                    expires = ?';
        $this->db->query($sql);
        $prep = $this->db->prepare($sql);
        $prep->bind_param('ssi', $id, $data, $time);
        $prep->execute();
    }
}

Ce que vous pouvez faire ici, c'est que vous pouvez exécuter votre propre script de nettoyage ici. À présent, je vous suggérerais d’utiliser un magasin de mémoire intermédiaire (memcached, Redis, etc.) afin de ne PAS charger à partir de la base de données à chaque fois. Vous voudrez nettoyer cela lorsque vous exécuterez votre script de nettoyage (c.-à-d. Extraire toutes les sessions sur le point d'expirer et les supprimer du cache). Mais une simple instruction SQL ici (exécutée, par exemple, sur un travail cron de 5 minutes) nettoie les sessions à la demande.

 DELETE FROM your_session_table
 WHERE expires < now();
3
Machavity

Je pense que ce que vous cherchez peut être ici: Accéder aux sessions actives dans PHP

En résumé, vous devez créer votre propre gestionnaire de session. C'est le côté serveur.

Si vous souhaitez ajouter des alertes côté client, vous pouvez enregistrer le délai d'expiration de la session utilisé dans un minuteur javascript. S'il ne reste que x minutes, un message (avec éventuellement un compte à rebours) apparaîtra pour indiquer à l'utilisateur "Votre session expirera dans: (affichez la minuterie ici)." 

2
Jonny O

Vous pouvez stocker le temps de connexion quelque part (table, ...) afin de pouvoir voir depuis quand l'utilisateur a été connecté et faire une vérification régulière (cron ou service) pour voir si la date a dépassé une durée spécifique (5 minutes, .. .)

Mais si vous souhaitez avertir l'utilisateur (perte de document, ...), vous voudrez peut-être utiliser un code Javascript window.setTimeout côté client.

2
Goufalite

Chaque fois que vous envoyez une requête http au serveur, vérifiez le délai d'expiration de la session. si la session est valide faites votre travail, autrement réorientez-vous où vous voulez.

Ou

Vous pouvez faire une chose pour économiser votre temps. Créez une méthode qui vérifie la validité de la session en cours et appelez-la dans votre requête http. 

2
Dipankar Barman

Définir la session initiale sur une page.

exemple: Login.php

<?php
session_start();
if(...){
   // success
   $_SESSION['logged_time'] = time();
}
?>

maintenant vérifier la session expirée ou pas dans une autre page

exemple: Index.php

<?php
   session_start();
   $login_session_duration = 60; // 1 minute 

   if($_SESSION['logged_time']){
      if(((time() - $_SESSION['logged_time']) > $login_session_duration)){ 
         echo 'session expired';
         // session will be exired after 1 minutes
      }else{
         echo 'session alive';
      }
   }
?>
2
Anfath Hifans

Vous pouvez aussi utiliser ça :) 

<? 
session_start();

$time = 3600; // Set expire time with secends.
// Star session here 
if (isset($_SESSION['time']) && (time() - $_SESSION['time']) > $time) {
   // Your Code Here to logout
   header('location: /auth/logout');
   exit();
} else {
  $_SESSION['time'] = time();
 }
2
Wahid Lahouiter

Eh bien très simple moyen de faire est

obtenir current_time 

$current_time=time();

obtenir le délai d'expiration de session défini dans le fichier ini.

$maxlifetime = ini_get("session.gc_maxlifetime");

Utilisez cette valeur dans javascript/query et, une fois le temps écoulé, utilisez une alerte pour avertir l'utilisateur ou écrire un script que vous souhaitez effectuer.

OU

Vous pouvez stocker ces dates dans une variable de cookie distincte:

session_expire = 1525357483057

Mais l'utilisateur peut changer cette variable.

1
Null Pointer

Essayez de le comparer à session_cache_expire () s'il est égal à zéro, votre session est terminée. Devrait probablement être mis en œuvre sur votre gestionnaire d'actions. Cela ne définit pas votre session sur le serveur, cela résout uniquement le problème du navigateur de votre client sachant quand il expirera, ce qui sert de votre détection automatique ...

http://php.net/manual/en/function.session-cache-expire.php

0