web-dev-qa-db-fra.com

Déconnexion automatique en Angular 2 après quelques minutes

Je souhaite implémenter une fonctionnalité (dans Angular2), c'est-à-dire après la connexion, si un utilisateur maintient le navigateur inactif pendant 30 minutes, il devrait être déconnecté lorsqu'il reviendra après 30 minutes. Cela doit être fait uniquement par le frontal.

J'utilise angular CLI of Angular version 2.4

Comment puis-je implémenter cette fonctionnalité dans mon application Angular2?

6
Er Vipin Sharma
import { Injectable } from "@angular/core";
import { Router } from '@angular/router'
const MINUTES_UNITL_AUTO_LOGOUT = 60 // in mins
const CHECK_INTERVAL = 15000 // in ms
const STORE_KEY =  'lastAction';
@Injectable()
export class AutoLogoutService {
 public getLastAction() {
    return parseInt(localStorage.getItem(STORE_KEY));
  }
 public setLastAction(lastAction: number) {
    localStorage.setItem(STORE_KEY, lastAction.toString());
  }

  constructor(private router: Router) {
    this.check();
    this.initListener();
    this.initInterval();
    localStorage.setItem(STORE_KEY,Date.now().toString());
  }

  initListener() {
    document.body.addEventListener('click', () => this.reset());
    document.body.addEventListener('mouseover',()=> this.reset());
    document.body.addEventListener('mouseout',() => this.reset());
    document.body.addEventListener('keydown',() => this.reset());
    document.body.addEventListener('keyup',() => this.reset());
    document.body.addEventListener('keypress',() => this.reset());
  }

  reset() {
    this.setLastAction(Date.now());
  }

  initInterval() {
    setInterval(() => {
      this.check();
    }, CHECK_INTERVAL);
  }

  check() {
    const now = Date.now();
    const timeleft = this.getLastAction() + MINUTES_UNITL_AUTO_LOGOUT * 60 * 1000;
    const diff = timeleft - now;
    const isTimeout = diff < 0;

    if (isTimeout)  {
      localStorage.clear();
      this.router.navigate(['./login']);
    }
  }
}
5

J'avais besoin de faire quelque chose de similaire et j'ai créé ceci: https://github.com/harunurhan/idlejs

Ce n'est pas spécifiquement pour angulaire, mais il est écrit en TypeScript donc vous obtenez des saisies officielles.

Il est simple et configurable sans aucune dépendance. Quelques exemples:

import { Idle } from 'idlejs/dist';

// with predefined events on `document`
const idle = new Idle()
  .whenNotInteractive()
  .within(60)
  .do(() => console.log('IDLE'))
  .start();

Vous pouvez également utiliser des cibles d'événements et des événements personnalisés:

const idle = new Idle()
  .whenNot([{
    events: ['click', 'hover'],
    target: buttonEl,
  },
  {
    events: ['click', 'input'],
    target: inputEl,
  },
  ])
  .within(10)
  .do(() => called = true)
  .start();
5
harunurhan

Fondamentalement, ce que vous devez faire est de définir un indicateur en cas d'activité du client et après 30 minutes, vous devez vérifier cet indicateur. Si l'indicateur n'a pas été défini, cela signifie que l'utilisateur n'était pas actif, vous pouvez donc effectuer une action logout().

Voici un exemple de code (utilisant ngrx ) que vous pourriez trouver utile.

export class ClientActiveService {
  constructor(
    private store: Store<fromRoot.State>,
  ) { }

  run() {
    window.onload = () => { this.setActive(); };
    window.onmousemove = () => { this.setActive(); };
    window.onmousedown = () => { this.setActive(); }; 
    window.onclick = () => { this.setActive(); };
    window.onscroll = () => { this.setActive(); }; 
    window.onkeypress = () => { this.setActive(); };
  }

  setActive() {
     this.store.select(fromRoot.getClientActive)
     .take(1)
     .subscribe((active) => {
        if (!active) {
          this.store.dispatch(new layout.ClientActiveAction());
        }
      });
  }
}

ClientActiveService est un service qui émet simplement une action si le client était actif. Quelque part comme dans app.component.ts, Vous devez injecter ce service et appeler this.clientActiveService.run();

Ensuite, quelque part dans votre code, vous devez configurer un minuteur de 30 minutes où vous vous abonnez pour une action ClientInactiveAction

    setInterval(() => {
      this.store.select(fromRoot.getClientActive)
      .take(1)
      .subscribe((active) => {
        if (!active) {
          this.auth.logout();
        }
      });
    }, 30 * 60 * 1000);

Si vous n'utilisez pas ngrx , vous pouvez simplement définir un variable/flag À la place dans le service ClientActiveService. Ensuite, dans setTimeout() vérifiez simplement cette variable et effectuez votre action logout()

Sinon, vous voudrez peut-être utiliser la bibliothèque ng2-idle . Dans ce cas Angular 2 - Déconnexion avec ng2-idle pourrait aider.

2
kuncevic.dev