Domanda

La nostra applicazione si disconnette dopo 30 minuti e viene reindirizzata alla pagina di accesso, sto specificando il timeout della sessione in web.xml e utilizzo un requestProcessor per il reindirizzamento. Voglio mostrare all'utente un messaggio che dice che la tua sessione è scaduta una volta scaduta la sessione, come posso farlo. Disconnessione automatica?Vorrei visualizzare il messaggio di errore nella pagina "La sessione è scaduta, effettua nuovamente l'accesso".Allora come potrei rilevare che la sessione è timeout?ci saranno metodi che si attiveranno automaticamente?

È stato utile?

Soluzione

Creare un controllo dell'attività che controlla ogni minuto se qualsiasi attività utente ha avuto luogo (mouseclick, keypress) ed esegue un battito cardiaco al lato server per mantenere attiva la sessione quando l'utente è attivo e non fa nulla quando l'utente non è attivo.Quando non vi è attività per 30 minuti (o qualunque sia il timeout di sessione predefinito sia impostato sul lato server), quindi eseguire un reindirizzamento.

Ecco un esempio di kickoff con poca aiuto di jQuery per legare i clic e gli eventi del tasto di tasto e il fuoco Ajax richiesta.

<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
    $(document).ready(function() {
        $.active = false;
        $('body').bind('click keypress', function() { $.active = true; });
        checkActivity(1800000, 60000, 0); // timeout = 30 minutes, interval = 1 minute.
    });

    function checkActivity(timeout, interval, elapsed) {
        if ($.active) {
            elapsed = 0;
            $.active = false;
            $.get('heartbeat');
        }
        if (elapsed < timeout) {
            elapsed += interval;
            setTimeout(function() {
                checkActivity(timeout, interval, elapsed);
            }, interval);
        } else {
            window.location = 'http://example.com/expired'; // Redirect to "session expired" page.
        }
    }
</script>
.

Creare un Servlet che ascolta /heartbeat e fondamentalmente solo quanto segue:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    request.getSession();
}
.

per mantenere vivo la sessione.

Quando si memorizza l'utente loggato nella sessione, sarà "automagicamente" disconnesso ogni volta che la sessione scade.Quindi non è necessario disconnetti manualmente l'utente.

Altri suggerimenti

Creare una classe listener Implementazione HttpSessionListener e Definiscilo in Web.xml

Questo ti avviserà quando viene distrutta una sessione.Utilizzare il metodo sessionDestroyed().

Vedi un esempio completo qui:

http://www.mkyong.Com / Servlet / A-Simple-HTTPSessionListener-Esempio-Sessioni attive-contagi /

Potrebbe trattarsi di un semplice servlet, spring-mvc o spring-security. Il logout automatico non è possibile senza una perfetta logica lato client.
Considerando che l'applicazione avrà entrambi i tipi di richiesta

  • AJAX e
  • invio del modulo/ricaricamento della pagina

Il logout automatico richiede una logica molto calcolata.Presentando l'implementazione della mia funzionalità di logout automatico con quanto segue

Vantaggi.


1.Per raggiungere questo obiettivo non viene utilizzata alcuna chiamata/richiesta aggiuntiva.considerando l'impatto sulle prestazioni in caso di più di 10.000 utenti attivi e chiamate extra per ottenere il logout automatico.
2.Configurazione a una linea tramite tag.
3.Funziona perfettamente anche se l'utente apre più schede o più finestre.
4.Ti avvisa prima che siano trascorsi 30 secondi dall'invalidamento della sessione, quindi se hai compilato il modulo e non lo hai inviato, puoi mantenere attiva la sessione (estendere la sessione di un clic).Quindi l'utente ha meno probabilità di perdere i dati non salvati.

Utilizzo


1.Includere lo script di disconnessione automatica nelle pagine JSP richieste come indicato di seguito.

    ....
    </body>
    <jsp:include page="../template/autologout-script.jsp"></jsp:include>
</html>

2.Crea una pagina JSP, autologout-script.jsp e aggiungi il codice seguente.Nota:Non è richiesta alcuna modifica/configurazione

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<script>
$(document).ready(function()
{
    var timeOutTimeInSeconds = ${ timeOutTimeInSeconds }; 
    var showTimerTimeInSeconds= ${ showTimerTimeInSeconds };

    var sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
    var timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
    var badgeTimerId;
    window.localStorage.setItem("AjaxRequestFired", new Date());

    function redirectToLoginPage(){
        //location.href =  '<c:url value="/" />'+'${loginPageUrl}';
        window.location.reload();
    }

    $(document).ajaxComplete(function () {
        resetTimer();
    });

    $(window).bind('storage', function (e) {
         if(e.originalEvent.key == "AjaxRequestFired"){
             console.log("Request sent from another tab, hence resetting timer")
             resetTimer();
         }
    });

    function resetTimer()
    {
        showTimerTimeInSeconds= ${ showTimerTimeInSeconds };

        console.log("timeOutTimeInSeconds : "+timeOutTimeInSeconds)
        window.localStorage.setItem("AjaxRequestFired", new Date());

        window.clearInterval(sessionCheckIntervalId);
        sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);

        window.clearInterval(timerDisplayIntervalId);
        timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);

        hideTimer();
    }

    function showTimer()
    {
        $('#sessionTimeRemaining').show();
        $('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
        window.clearInterval(timerDisplayIntervalId);
        badgeTimerId = setInterval(function(){
            $('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
        }, 1000);
    }

    function hideTimer()
    {
        window.clearInterval(badgeTimerId);
        $('#sessionTimeRemaining').hide();
    }
});
</script>

3.Configurare gli attributi della sessione per configurare l'impostazione del timeoutNota:Configuralo dopo la creazione della sessione.È possibile implementare il metodo HttpSessionListener sessionCreated e impostare la seguente configurazione secondo le proprie esigenze.

session.setMaxInactiveInterval(300);

session.setAttribute("timeOutTimeInSeconds", 300);
session.setAttribute("showTimerTimeInSeconds", 30);

4.Aggiungi sotto l'html per la visualizzazione del timer.
Nota:può essere spostato nella pagina del modello di script di logout automatico se sei bravo con i CSS.Quindi puoi evitare di aggiungerlo in ogni pagina.
Includi bootstrap o aggiungi il tuo CSS personalizzato.

<span class="badge badge-primary" title="click to keep session alive" id="sessionTimeRemaining" 
    onclick="ajaxSessionRefresh()" style="display:none;">
    <i class="badge badge-danger" id="sessionTimeRemainingBadge" style="float:left">30</i>
     &nbsp; 
     <small>Refresh</small>
     <i class="glyphicon glyphicon-refresh"></i>
</span>

enter image description here

Si tratta di una semplice implementazione del logout automatico.Puoi scaricare un esempio funzionante dal mio repository github
Logout automatico utilizzando un semplice esempio di servlet
Logout automatico utilizzando l'esempio di configurazione Java di Spring-Security
Logout automatico utilizzando l'esempio di configurazione xml di spring-security

Logica spiegata


Caso 1:Al caricamento della pagina
Qui la logica è semplice, al caricamento della pagina impostare il timer dell'intervallo equivale a maxInactiveInterval.dopo il timeout reindirizza alla pagina di accesso.
Caso 2:Tieni traccia delle chiamate AJAX
Ora considerando le richieste AJAX, puoi utilizzare i callback .ajaxStart() o .ajaxComplete() di jquery in modo che se viene attivata una richiesta Ajax puoi reimpostare l'intervallo.
Caso 3:Monitoraggio dell'attività di più schede/finestre
La comunicazione tra schede viene eseguita per sincronizzare lo stato di ciascuna scheda.LocalStorage utilizzato nell'evento di modifica.

Limitazioni/miglioramenti richiesti
1.Se la sessione massima consentita è una, se la sessione viene presa da un altro sistema, la richiesta AJAX fallirà.È necessario gestirlo per reindirizzare alla pagina di accesso.
2.Utilizza ajaxStart() invece di ajaxComplete() per avere la sincronizzazione esatta dei valori idleTime tra server e browser.

Requisiti
1.Jquery

Alternative all'implementazione attuale a confronto


1. Impostazione Aggiorna intestazione nella risposta http. (Non funziona per le richieste AJAX)

response.setHeader("Refresh", "60; URL=login.jsp");
  1. Impostazione del tag di meta aggiornamento nell'HTML (Non funziona per le richieste AJAX)
<meta http-equiv="refresh" content="60; url=login.jsp">
  1. Configurazione del controllo attivitàMantiene attiva la sessione tramite ripetute richieste AJAX.Tiene traccia del tempo di inattività ed effettua la richiesta di disconnessione dopo il timeout.
    Senza dubbio è buono con una logica semplice.Ma voglio solo scrivere le mie osservazioni.
    • Impatto sulle prestazioni se vengono effettuate 2 richieste al minuto per mantenere attiva la sessione e 50k utenti attivi.100.000 richieste al minuto.
    • Comunicazione intertab Se due schede sono aperte, una scheda riceve attività ma l'altra scheda non riceve attività, tale scheda attiva la richiesta di disconnessione e invalida la sessione anche se l'attività è presente nell'altra scheda.(Ma può essere gestito)
    • Approccio di disconnessione forzata È un client che è dominato dal server per invalidare la sessione.

Se si utilizzano sessioni del servlet, è possibile verificare se la sessione in cui il JSP / Servlet è in ritorno è nuovo utilizzando il metodo ISNew ().Se sì, la sessione dell'utente è scaduta e è possibile visualizzare i messaggi pertinenti.

Includi una funzione di utilità JavaScript all'interno del JSP e Ping del server ogni 31 minuti. La funzione di utilità sopra citata dovrebbe utilizzare Settentimeout () Funzione JS internamente.

setTimeout ( "checkServerSession()",  /* intervalInMilliSeconds */ 31000);
.

nota che

.

CheckserverSession ()

è una regolare funzione JS che potrebbe attivare le richieste HTTP.Se la richiesta è la sessione riuscita esiste altrimenti mostra il prompt all'utente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top