javascript - Timeout e gestione della sessione angolare




angularjs session-timeout (4)

Sto usando ng-idle da un po 'di tempo per i requisiti inferiori.

Il nostro requisito era quando l'utente è inattivo per 60 minuti. Dopo 55 minuti, mostrare il pop-up con la casella di conferma che dice di voler continuare la sessione o meno (ho usato un avviso dolce). Se l'utente fa clic su Continua, ripristina l'ora di inattività, altrimenti effettua la disconnessione forzata chiamando il metodo di trasmissione.

La configurazione deve essere eseguita in app.js quando gli utenti eseguono il login all'interno di app.config come di seguito

app.config(['KeepaliveProvider', 'IdleProvider', function (KeepaliveProvider, IdleProvider) {
IdleProvider.idle(TimeOut.firstAPiCall);--It will call Idle On method
IdleProvider.timeout(TimeOut.SessionTimeOut);--It will be called when the total time is (TimeOut.firstAPiCall +TimeOut.SessionTimeOut)
KeepaliveProvider.interval(TimeOut.interval);}]) --It will be called like a heart beat for mentioned timeout until the idle start has not occured.

Di seguito è riportato il codice per la visualizzazione di pop-up

   $scope.$on('IdleStart', function () {   
    $scope.$broadcast('SessionIdleUpdate', 'IdleStart', TimeOut.FirstApicall);
    $rootScope.idleTimerSession = setTimeout(function () {
        console.log("pop up appeared on : " + new Date())
        $scope.timedout = SweetAlert.swal({
            title: "Alert",
            text: "Your session is about to expire in 5 minutes, Do you want to continue?",
            type: "warning",
            showCancelButton: true,
            confirmButtonColor: "#DDDDD",
            confirmButtonText: "CONTINUE",
            cancelButtonText: "No"
        }, function (isConfirm) {
            if (isConfirm) {
                clearTimeout(idleTimer);
            }
            else {
                console.log("pop up closed from confirm on  : " + new Date())
                $scope.$broadcast('SessionTimeOutLogOut', null);
                Idle.unwatch();
                $scope.started = false;
            }
        });

        //This check is to handle idle pop up if it appears and user doesnt perform any action it will simply logout.
        var idleTimer = setTimeout(function () {

            swal.close();            
            $scope.$broadcast('SessionTimeOutLogOut', null);
            Idle.unwatch();
            $scope.timedout = null;
        }, (TimeOut.sessionTimeOut) * 1000);
    }, (TimeOut.idleTimeOut - TimeOut.idleCheckDuration) * 1000);-- Time out is added to hold the pop up for that much duration . Because once the idle start is occured you wont be able to call the API 

});

Di seguito è riportato il codice per la gestione degli eventi di fine inattività:

  $scope.$on('IdleEnd', function () {
        $scope.$broadcast('SessionIdleUpdate', 'IdleEnd', 0));    
    clearTimeout($rootScope.idleTimerSession);
    closeModals();
});

Di seguito è riportato il codice per Time Out che verrà chiamato dopo --- (TimeOut.firstAPiCall + TimeOut.SessionTimeOut)

  $scope.$on('IdleTimeout', function (forceLogout) {


        swal.close();
        $scope.$broadcast('SessionTimeOutLogOut', null);
        Idle.unwatch();

});

Questa domanda ha già una risposta qui:

C'è un modo per gestire la sessione utente usando Angularjs?, Voglio dire ::

  • Timeout sessione: quando il sistema è inattivo.
  • Avvisa quando la sessione sta per scadere con l'opzione di riprendere la sessione.
  • Reindirizzamento (o qualsiasi altra azione) quando si tenta di effettuare una richiesta se la sessione è scaduta.

Potrebbe essere Interceptor una buona opzione per risolvere questo problema? Puoi fornire un esempio?

Grazie in anticipo.


Prova ng-idle . È un componente semplice in cui è possibile impostare il timeout e il tempo di avviso prima che venga raggiunto il timeout. Quindi è possibile interrogare il server per il logout dell'utente o qualcosa di simile.

myApp.config(function(IdleProvider, KeepaliveProvider) {
  IdleProvider.idle(900); // 15 min
  IdleProvider.timeout(60);
  KeepaliveProvider.interval(600); // heartbeat every 10 min
  KeepaliveProvider.http('/api/heartbeat'); // URL that makes sure session is alive
});

myApp.run(function($rootScope, Idle) {
  Idle.watch();
  $rootScope.$on('IdleStart', function() { /* Display modal warning or sth */ });
  $rootScope.$on('IdleTimeout', function() { /* Logout user */ });
});

Nella configurazione precedente, quando l'utente è inattivo per 900 s (non muove il mouse, premere un tasto o un pulsante, ecc.), Viene visualizzato un avviso. Attenderà quindi 60 secondi e disconnetterà l'utente (invia una richiesta a un server che probabilmente distrugge la sessione del server).

Per assicurarsi che la sessione del server non scada (anche se tutto ciò che l'utente sta facendo è spostare il mouse), il servizio Keepalive invierà una richiesta al server ogni 10 minuti. Questa volta deve essere inferiore alla scadenza della sessione del server.

Acquista la demo .



È possibile aumentare la sicurezza nel processo di autenticazione utilizzando JWT (Token Web JSON) e SSL / HTTPS.

L'autenticazione di base / ID sessione può essere rubato tramite:

  • Attacco MITM (Man-In-The-Middle) - senza SSL / HTTPS
  • Un intruso che accede al computer di un utente
  • XSS

Utilizzando JWT stai crittografando i dettagli di autenticazione dell'utente e memorizzandoli nel client e inviandoli insieme ad ogni richiesta all'API, dove il server / API convalida il token. Non può essere decodificato / letto senza la chiave privata (che il server / API archivia segretamente) Leggi l'aggiornamento .

Il nuovo flusso (più sicuro) sarebbe:

Accesso

  • L'utente accede e invia le credenziali di accesso all'API (su SSL / HTTPS)
  • API riceve le credenziali di accesso
  • Se valido:
    • Registra una nuova sessione nel database Leggi l'aggiornamento
    • Criptare ID utente, ID sessione, indirizzo IP, data e ora, ecc. In un JWT con una chiave privata.
  • L'API invia di nuovo il token JWT al client (su SSL / HTTPS)
  • Il client riceve il token JWT e lo memorizza in localStorage / cookie

Ogni richiesta all'API

  • L'utente invia una richiesta HTTP all'API (su SSL / HTTPS) con il token JWT memorizzato nell'intestazione HTTP
  • API legge l'intestazione HTTP e decrittografa il token JWT con la sua chiave privata
  • API convalida il token JWT, corrisponde all'indirizzo IP della richiesta HTTP con quello nel token JWT e verifica se la sessione è scaduta
  • Se valido:
    • Restituisci la risposta con il contenuto richiesto
  • Se non valido:
    • Eccezione di tiro (403/401)
    • Segnala un'intrusione nel sistema
    • Invia un messaggio di posta elettronica all'utente.

Aggiornato il 30.07.15:

Il carico utile / attestazioni JWT può essere letto senza la chiave privata (segreto) e non è sicuro per memorizzarlo in localStorage. Mi dispiace per queste dichiarazioni false. Tuttavia sembra che stiano lavorando su uno standard JWE (JSON Web Encryption) .

L'ho implementato memorizzando le attestazioni (userID, exp) in un JWT, l'ho firmato con una chiave privata (segreta), l'API / backend sa solo e memorizzato come cookie HttpOnly sicuro sul client. In questo modo non può essere letto tramite XSS e non può essere modificato, altrimenti il ​​JWT fallisce la verifica della firma. Inoltre, utilizzando un cookie HttpOnly sicuro , ci si assicura che il cookie venga inviato solo tramite richieste HTTP (non accessibili allo script) e inviato solo tramite connessione protetta (HTTPS).

Aggiornato il 17.07.16:

I JWT sono per natura apolidi. Ciò significa che invalidano / espirano. Aggiungendo il SessionID nelle affermazioni del token lo stai rendendo statico, poiché la sua validità non dipende solo dalla verifica della firma e dalla data di scadenza, ma dipende anche dallo stato della sessione sul server. Tuttavia, il lato positivo è che puoi invalidare facilmente token / sessioni, cosa che non avresti potuto fare prima con i JWT stateless.





javascript angularjs session-timeout