Idle timeout is one of the feature to enhance security by enforce logout if not used.
In Angular, idle timeout can be done by rxjs. This demo will show the steps on adding and enable this feature.
Prerequisites
- Angular CLI should be install. If not, execute command below.
npm -i @angular/cli -g
Steps
- Create new service.
In terminal, input command below to generate new service named IdleService.ng generate service Idle ## Or simply use short cut parameter. ng g s Idle
- Alter Idle service code.
Open idle-service.ts and alter code as below.import { Injectable } from '@angular/core'; import { Observable, fromEvent, merge, Subject, timer, Subscription } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class IdleService { private idle: Observable<any> = new Observable(); private timer :Subscription = new Subscription(); private timeOutMilliSeconds: number = 1000; private idleSubscription: Subscription = new Subscription(); public expired: Subject<boolean> = new Subject<boolean>(); public startWatching(timeOutSeconds : number): Observable<any> { this.idle = merge( fromEvent(document, 'mousemove'), fromEvent(document, 'click'), fromEvent(document, 'mousedown'), fromEvent(document, 'keypress'), fromEvent(document, 'DOMMouseScroll'), fromEvent(document, 'mousewheel'), fromEvent(document, 'touchmove'), fromEvent(document, 'MSPointerMove'), fromEvent(window, 'mousemove'), fromEvent(window, 'resize'), ); this.timeOutMilliSeconds = timeOutSeconds * 1000; this.idleSubscription = this.idle.subscribe((res) => { this.resetTimer(); }); this.startTimer(); return this.expired; } private startTimer() { this.timer = timer(this.timeOutMilliSeconds, this.timeOutMilliSeconds).subscribe((res) => { this.expired.next(true); }); } public resetTimer() { this.timer.unsubscribe(); this.startTimer(); } public stopTimer() { this.timer.unsubscribe(); this.idleSubscription.unsubscribe(); } }
- Update environment settings.
To make timeout configurable, suggest split it to environment file. Open environment.ts and alter code as below.
This demo will set timeout after 5 minutes.export const environment = { idleTimeInMinutes: 5 };
- Enable idle service.
In app-component.ts, alter code as below.export class AppComponent implements OnInit { constructor(private router: Router, private idleService: IdleService) { } ngOnInit(): void { this.initialIdleSettings(); } private initialIdleSettings() { const idleTimeoutInSeconds: number = environment.idleTimeInMinutes * 60; this.idleService.startWatching(idleTimeoutInSeconds).subscribe((isTimeOut: boolean) => { if (isTimeOut) { alert("Session timeout. It will redirect to login page."); } }); } }
- Test to verify.
Run application and wait for 5 minutes without action. If dialog prompted, it means code can executed successfully.
Related sample project has been update to GitHub repository.
not redirecting to login page
Putting your code (after refactor) in a library will definitely help even more people.
It has a long time not update that, will create a sample project and put it in there. Thanks for suggestion.
But i problem please give your suggestion
What if i remove dialog prompted from element (inspect element). I want to secure this.
You can replace the alert() to other business logic or use 3rd party component to replace it.
Alert() is a sample to status the result so no worry on replace it.
What if app pages opened in multiple tabs
The timer will still count unless you set handler for event visibilityChange to start / stop timer.
Ref: https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event
working fine for all the events. while playing a video it should be active but it is showing alert message. what event i need to add for that.
Assume u are play video in video tag, u can add the eventListener onPlay to stop counter.