Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatic logout in Angular 2 after few minutes

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?

like image 702
Er Vipin Sharma Avatar asked Aug 28 '17 04:08

Er Vipin Sharma


People also ask

How do I automatically logout of react JS?

When component mounts, add listeners to the window that listens to the events. Create a function that logs out user after 10 secs using setTimeout . Each time any of the event is triggered, i.e mousemove , click , scroll , keypress etc, the timer to logout user after 10 secs of inactivity resets.


3 Answers

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']);
    }
  }
}
like image 60
Nabin Kumar Khatiwada Avatar answered Oct 17 '22 05:10

Nabin Kumar Khatiwada


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();
like image 7
harunurhan Avatar answered Oct 17 '22 04:10

harunurhan


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.

like image 3
angularrocks.com Avatar answered Oct 17 '22 03:10

angularrocks.com