Automatic logout in Angular 2 after few minutes

22,551

Solution 1

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']);
    }
  }
}

Solution 2

I needed to do similar thing and created this: https://github.com/harunurhan/idlejs

It is not specifically for angular, but it is written in typescript so you get official typings.

It is simple and configurable without any dependencies. Some examples:

import { Idle } from 'idlejs/dist';

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

You can also use custom event targets and events:

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

Solution 3

Basically what you need to do is to set a flag in case of any client activity and than after 30 minutes you have to check for that flag. If flag wasn't set which means user wasn't being active so you can perform a logout() action.

Here is some code sample(using ngrx) that you might find useful.

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 is a service that just emmiting an action if client was active. Somewhere like in app.component.ts you have to inject that service and call this.clientActiveService.run();

Then somewhere in your code you have to setup a 30 minutes timer where you subscribe for an ClientInactiveAction action

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

If you are not using ngrx you can just set a variable/flag instead in ClientActiveService service. Then in setTimeout() just check for that variable and perform your logout() action

Otherwise you might wanna use ng2-idle library. In that case Angular 2 - Logout using ng2-idle might help.

Share:
22,551
Er Vipin Sharma
Author by

Er Vipin Sharma

frontend Developer working on Angular 2 in Noida,India.

Updated on July 05, 2022

Comments

  • Er Vipin Sharma
    Er Vipin Sharma almost 2 years

    I want to implement a feature (in Angular2) i.e. After login, if a user keeps browser idle for 30 minutes, he should be logged out when coming back after 30 minutes. This has to be done by the front end only.

    I am using angular CLI of Angular version 2.4

    How can I implement this feature in my Angular2 application?