Creating a Session Timeout Function, Which Can Display Timer and Redirect to Previous Page on Timeout in Angular

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

enter image description here

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:

  1. Avoiding frustration for losing unsaved work during redirects.
  2. 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?

  1. On a successful 1st login, write the date/time that the session will
    expire into localStorage e.g new Date() + 30 minutes.
  2. Inject e.g authentication.service.ts at the app level, which will
    have a setInterval(() => checkSessionTimeout(), e.g every 1 minute)
    inside its constructor. This approach will ensure that this method
    will run on new tabs / windows as well.
  3. Create a method checkSessionTimeout() that outputs how many minutes
    remaining until session timeout and write it into a variable in
    authentication.service.ts e.g sessionTimeoutIn: number;
  4. 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>
  5. For the blurring effect, add a class to your body / main with [class.blur]="authenticationService.sessionTimeoutIn <= 0"
  6. 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>
    :

enter image description here

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



Leave a reply



Submit