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?
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.
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']);
}
}
}
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();
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 inClientActiveService
service. Then insetTimeout()
just check for that variable and perform yourlogout()
action
Otherwise you might wanna use ng2-idle library. In that case Angular 2 - Logout using ng2-idle might help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With