Creating a session timeout function, which can display timer and redirect to previous page on timeout in angular
import { Location } from '@angular/common';
timer = {s: 0, mn: 0};
constructor(private location: Location) {
setTimeout(() => {
this.location.back();
}, 300000);
setInterval(() => {
this.timer.s += 1;
if (this.timer.s > 59) {
this.timer.s = 0;
this.timer.mn += 1;
}
}, 1000);
}
Now you can display a timer and the user will be redirected.
If you want a reverted timer :
this.timer.s -= 1;
if (this.timer.s < 0) {
this.timer.s = 59;
this.timer.mn = -1;
}
How to give session idle timeout in angular 6?
You can use bn-ng-idle npm for user idle / session timeout detection in angular apps. This blog post explanation will help you Learn how to Handle user idleness and session timeout in Angular
npm install bn-ng-idle
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { BnNgIdleService } from 'bn-ng-idle'; // import bn-ng-idle service
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [BnNgIdleService], // add it to the providers of your module
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.ts
import { Component } from '@angular/core';
import { BnNgIdleService } from 'bn-ng-idle'; // import it to your component
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private bnIdle: BnNgIdleService) { // initiate it in your component constructor
this.bnIdle.startWatching(300).subscribe((res) => {
if(res) {
console.log("session expired");
}
})
}
}
In the above example, I have invoked the startWatching(timeOutSeconds)
method with 300 seconds (5 minutes) and subscribed to the observable, once the user is idle for five minute then the subscribe method will get invoked with the res parameter's value (which is a boolean) as true.
By checking whether the res is true or not, you can show your session timeout dialog or message. For brevity, I just logged the message to the console.
Angular session timeout and management
Try ng-idle. It's simple component where you can set the timeout and warning time before the timeout is reached. Then you can query server for user logout or something similar.
myApp.config(function(IdleProvider, KeepaliveProvider) {
IdleProvider.idle(900); // 15 min
IdleProvider.timeout(60);
KeepaliveProvider.interval(600); // heartbeat every 10 min
KeepaliveProvider.http('/api/heartbeat'); // URL that makes sure session is alive
});
myApp.run(function($rootScope, Idle) {
Idle.watch();
$rootScope.$on('IdleStart', function() { /* Display modal warning or sth */ });
$rootScope.$on('IdleTimeout', function() { /* Logout user */ });
});
In the above configuration, when user is idle for 900s (does not move mouse, press any key or button etc), warning is being displayed. It will then wait 60s and log out user (send request to a server that possibly destroys server session).
In order to make sure server session does not expire (even if everything user is doing is moving mouse) the Keepalive
service will send a request to the server every 10 minutes. This time has to less than server session expiration time.
Checkout the demo.
Angular 4 redirect after inactivity
You need a timer which counts backwards and gets resetted when user action comes up. To track user action you can use a host listener:
@HostListener('document:keyup', ['$event'])
@HostListener('document:click', ['$event'])
@HostListener('document:wheel', ['$event'])
resetTimer () {
// user action occured
}
And a timer would be something like this:
endCount = new Subject();
// end time in minutes
private initTimer (endTime: number) {
const interval = 1000;
const duration = endTime * 60;
this.subscription = Observable.timer(0, interval)
.take(duration)
.subscribe(value => this.render((duration - +value) * interval),
err => { },
() => {
this.endCount.next();
});
}
private render (count) {
this.secondsDisplay = this.getSeconds(count);
this.minutesDisplay = this.getMinutes(count);
}
private getSeconds (ticks: number) {
const seconds = ((ticks % 60000) / 1000).toFixed(0);
return this.pad(seconds);
}
private getMinutes (ticks: number) {
const minutes = Math.floor(ticks / 60000);
return this.pad(minutes);
}
private pad (digit: any) {
return digit <= 9 ? '0' + digit : digit;
}
Listen on endCount to get notified when user was inactive for a period of time.
To reset the timer:
resetTimer (newEndTime) {
this.clearTimer();
this.initTimer(newEndTime);
}
clearTimer () {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
Stackblitz Example: https://stackblitz.com/edit/angular-2rv3or
How to deal with session timeout (or expired token), when there is no routing on link in angular 4
In our environment, to provide the best UX possible, users are not redirected to the login page on session expiry.
Instead, the entire page is blurred and a modal is shown that requires a password input and contains a submit button as above.
Main advantages of this approach are:
- Avoiding frustration for losing unsaved work during redirects.
- A more seemless re-authentication experience.
Similar to some of the answers described here - https://ux.stackexchange.com/questions/7195/best-practices-for-warning-of-session-expiration
How to achieve this in Angular?
- On a successful 1st login, write the date/time that the session will
expire into localStorage e.gnew Date() + 30 minutes.
- Inject e.g
authentication.service.ts
at the app level, which will
have asetInterval(() => checkSessionTimeout(), e.g every 1 minute)
inside its constructor. This approach will ensure that this method
will run on new tabs / windows as well. - Create a method
checkSessionTimeout()
that outputs how many minutes
remaining until session timeout and write it into a variable inauthentication.service.ts
e.gsessionTimeoutIn: number;
- Create a component that will contain the re-authenticate modal as
shown in the image above. Inject this component at the app level
with<app-re-authenticate-modal *ngIf="authenticationService.sessionTimeoutIn <= 0"></app-re-authenticate-modal>
- For the blurring effect, add a class to your body / main with
[class.blur]="authenticationService.sessionTimeoutIn <= 0"
- For even better experience, create a div that pushes the main /
body, and enters the view from the top that contains this, which can
be controlled with<div
:
*ngIf="authenticationService.sessionTimeoutIn > 0 && authenticationService.sessionTimeoutIn <= 2"></div>
After these, the user should not be able to attempt to do anything other than re-authenticating, and you can still use your AuthenticationGuards.
Hope it helps.
Related Topics
How to Change Background Opacity When Bootstrap Modal Is Open
How to Select Every 2Nd Element of an Array in a for Loop
Property Does Not Exist on Type 'Never' Typescript/React
How to Reload Datatable by Ajax (Jquery)
Charts.Js Graph Not Scaling to Canvas Size
Search Bar With Dropdown Results
Android Webview Not Loading Website Properly
Formatting a Number to Have Commas At Every 1000 Factor
Window.Opener | Not Working in Chrome
How to Reset Child Elements' State
Find Duplicate Values in Objects With JavaScript
Regex to Match 2 Different Words in a String
How to Match Only the Exact Word Using Indexof or Includes in JavaScript
Alphanumeric, Dash and Underscore But No Spaces Regular Expression Check JavaScript
Update Value in Localstorage Array by Existing Key
How to Get the Ajax Response from Success and Assign It in a Variable Using Jquery