2012-02-18 15 views
9

Sto lavorando a un'applicazione che ospita diverse applicazioni secondarie e vorrei implementare un logout automatico dopo 30 minuti di inattività. Ho un AuthController con Accesso e uscita azioni mappati custom/login e percorsi/logout utilizzando il bootstrap.php così come un plugin front controller che assomiglia a questo:Zend Framework Logout automatico dopo inattività

class Plugin_SessionTrack extends Zend_Controller_Plugin_Abstract { 

    public function preDispatch(Zend_Controller_Request_Abstract $request) 
    { 

     $employeeSession = new Zend_Session_Namespace('employeeSession'); 
     $employeeSession->setExpirationSeconds(10); 

    } 
} 

Sono nuovo di PHP e Zend , cosa sta succedendo esattamente alla sessione dopo 10 secondi? Ho messo basso per il test. Quello che mi piacerebbe che succedesse è se il tempo dell'ultima richiesta attraverso il plugin del front controller era superiore a 30 minuti fa, distruggi la sessione e logga l'utente e reindirizzalo su/login.

Posso vedere chiaramente che non sto seguendo il tempo dell'ultima richiesta, ma la mia speranza era che il setExpirationSeconds sarebbe stato aggiornato ogni volta che l'utente ha ricevuto una richiesta attraverso questo metodo preDispatch.

Forse un cookie deve essere utilizzato? Non ho bisogno di avviare realmente un'azione di disconnessione, può essere gestita solo la prossima volta che l'utente fa una richiesta, se non hanno fatto nulla nell'ultima mezz'ora la sessione è stata distrutta e sono stati disconnessi, il che significa se esco per 45 minuti il ​​mio schermo sembra sempre lo stesso, ma se clicco su un link o provo a inviare un modulo che ho ricevuto, mi manda a/login. Posso preoccuparmi di qualche tipo di avviso per il conto alla rovescia di JS in seguito.

Edit: Ecco il mio bootstrap se qualcuno vuole vederlo:

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap 
{ 
    /** 
    * Custom routes: 
    * 
    * /login 
    * /logout 
    */ 
    protected function _initRoutes() 
    { 

     $router = Zend_Controller_Front::getInstance()->getRouter(); 

     $loginRoute = new Zend_Controller_Router_Route('login', array('controller' => 'auth', 'action' => 'login')); 

     $logoutRoute = new Zend_Controller_Router_Route('logout', array('controller' => 'auth', 'action' => 'logout')); 

     $routesArray = array('login' => $loginRoute, 'logout' => $logoutRoute); 

     $router->addRoutes($routesArray); 

    } 

    protected function _initPlugins() 
    { 

     $frontController = Zend_Controller_Front::getInstance(); 
     $frontController->registerPlugin(new Plugin_SessionTrack()); 

    } 
} 
+0

Prima definire "inattività". Tutto quello che possiamo vedere in php sono le richieste del server. Odio davvero suggerire questo, ma si consiglia di utilizzare javascript per monitorare l'attività e quando 'timeout' chiama il metodo di logout. La scadenza dello spazio dei nomi non sembra fare ciò di cui hai bisogno. – RockyFord

+0

L'inattività indica che l'utente non ha eseguito il POST di un modulo, non ha eseguito azioni nel controller. Fondamentalmente sono "Lontano dalla tastiera". Le applicazioni secondarie di questo case sono piuttosto guidate dai dati, quindi dovrebbe essere evidente che non stanno usando l'applicazione se le cose non stanno colpendo i controller (azioni). –

risposta

11

Quando si chiama Zend_Session::setExpirationSeconds(10), nulla è realmente accadendo alla sessione dopo 10 secondi di tempo per sé.

Questa chiamata fa sì che Zend_Session memorizzi un valore interno che contrassegna lo spazio dei nomi di sessione per scadenza a time() + $seconds dal momento in cui viene effettuata la chiamata. Ogni volta che si avvia uno Zend_Session, viene verificato se i dati di sessione sono contrassegnati per la scadenza e, in tal caso, procede a verificare se il tempo di scadenza o il conteggio degli hop sono passati. In tal caso, i dati della sessione in questione non vengono impostati all'inizializzazione e pertanto non sono più accessibili dall'applicazione.

Se si effettua questa chiamata all'inizio di ogni richiesta, è necessario continuare a prolungare la durata della sessione di quel numero di secondi per ogni caricamento della pagina.

Ricordare che se le impostazioni di sessione in php.ini sono impostate per scadere della sessione dopo 15 minuti, l'impostazione di uno spazio dei nomi che scade dopo 60 minuti non sostituirà la durata della sessione di PHP di 15 minuti. È possibile apportare tali modifiche alle direttive di sessione di PHP nel proprio file application.ini.

L'impostazione di una scadenza sul namespace ha anche il vantaggio di rimuovere automaticamente alcuni dati di sessione senza dover distruggere l'intera sessione.

Non conosco le specifiche dell'applicazione, ma è possibile utilizzare il plug-in per controllare e vedere se sono disconnessi e inoltrare la richiesta alla pagina di accesso. È possibile verificare un accesso valido dopo aver creato lo spazio dei nomi, ma si vorrebbe anche assicurarsi che la richiesta corrente non fosse un tentativo di accesso. Oppure puoi semplicemente rinviare il controllo di un login valido nel plugin e lasciare che il tuo ACL gestisca quello più tardi a livello di controller.

Si potrebbe anche voler esaminare Zend_Auth che è possibile utilizzare per mantenere un'identità nella sessione. L'identità può essere qualsiasi cosa, da un semplice valore booleano che indica se sono connessi, a un oggetto utente completo che implementa Zend_Acl_Role_Interface.Zend Auth è anche facilmente estendibile in modo che tu possa avere più sessioni Zend_Auth attive contemporaneamente utilizzando diversi spazi dei nomi per ogni istanza e che la tua classe di autenticazione personalizzata possa impostare limiti di tempo diversi su spazi dei nomi di diverse sessioni.

Spero che questo aiuti a rispondere alla tua domanda, sentiti libero di commentare se hai domande su ciò che ho detto.

EDIT:

ho provato il seguente codice ed è scaduto con successo la mia identità Zend_Auth dopo il tempo impostato. L'ho provato basso con 60 secondi e dopo aver atteso 60 secondi per caricare la pagina, non avevo più identità e sono stato "disconnesso". Puoi aggiungerlo al tuo plug-in di sessione.

<?php 
$auth = Zend_Auth::getInstance(); 

if ($auth->hasIdentity()) { // user is logged in 
    // get an instance of Zend_Session_Namespace used by Zend_Auth 
    $authns = new Zend_Session_Namespace($auth->getStorage()->getNamespace()); 

    // set an expiration on the Zend_Auth namespace where identity is held 
    $authns->setExpirationSeconds(60 * 30); // expire auth storage after 30 min 
} 
+0

https://gist.github.com/8b2ae80e23543a34ca8a C'è la mia azione di accesso. Sto utilizzando un adattatore Zend_Auth per autenticarli tramite Active Directory. Ho tutto funzionante tranne che per poter forzare un logout del loro utente se l'ultima azione intrapresa sul sito era> 30 minuti fa. –

+0

Più avanti nella tua applicazione, che cosa fai per verificare se un utente ha effettuato l'accesso? Ti basta controllare di vedere che l'identità dell'autentica non sia nulla? Vedi la mia risposta aggiornata che mostra come scadere l'identità di Zend_Auth. Spero che sia quello che stavi cercando. – drew010

+0

Sì, più tardi, se ho bisogno di vedere se sono loggati, prendo semplicemente getIdentity() e vedo come appare. Quindi, quando l'impostazione di $ authns scade tra 30 minuti, questo renderà un buon getIdentity() precedente a zero? –