Warn And Log Out User Due To Inactivity In Angular App

nightwolfdev - Mar 28 - - Dev Community

Protecting sensitive data from unauthorized access is an important aspect to securing a web application. Implementing an automatic log out feature due to an inactive user can help with that. Let’s learn how!

Package Installation

Install the @ng-idle/core package by running the following command:

npm install @ng-idle/core
Enter fullscreen mode Exit fullscreen mode

Package Setup

In order to use the package, you need to provide it at the root of the application. Depending on your Angular setup and version, you’ll need to do one of the following:

app.module.ts

import { NgIdleModule } from '@ng-idle/core';

@NgModule({
  providers: [
    NgIdleModule.forRoot()
  ]
})
Enter fullscreen mode Exit fullscreen mode

app.config.ts

import { importProvidersFrom } from '@angular/core';
import { NgIdleModule } from '@ng-idle/core';

export const appConfig: ApplicationConfig = {
  providers: [
    importProvidersFrom(NgIdleModule.forRoot())
  ]
};
Enter fullscreen mode Exit fullscreen mode

Warn User With App Alert

When the user becomes inactive, let’s provide a warning with a countdown. I’m using Clarity’s alert component, specifically an app level alert since it appears at the top of the app. Make sure to place it in a location that appears no matter what page you’re on.

@if (inactiveUser) {
  <clr-alert [clrAlertAppLevel]="true" [clrAlertClosable]="false" [clrAlertType]="'warning'">
    <clr-alert-item>
      <span class="alert-text">Logging out in {{ inactiveCountdown }} seconds due to inactivity.</span>
    </clr-alert-item>
  </clr-alert>
}
Enter fullscreen mode Exit fullscreen mode

We wrap the alert in an if statement and only display it if inactiveUser is true. We’ll see how that variable is defined in a moment.

By the way, you can also use ngIf on clr-alert instead of @if if you’re not yet on an Angular version that supports @if.

Handle Inactive User

Within your app component, let’s set up everything to handle an inactive user. Let’s start by importing what we need from the @ng-idle/core package.

import { DEFAULT_INTERRUPTSOURCES, Idle } from '@ng-idle/core';
Enter fullscreen mode Exit fullscreen mode

Create a variable called idle for the idle service in the component constructor.

constructor(private idle: Idle) {}
Enter fullscreen mode Exit fullscreen mode

Within the app component class, create a variable called inactiveCountdown, which will be of type number. This will count down the number of seconds before a user times out.

inactiveCountdown: number;
Enter fullscreen mode Exit fullscreen mode

Create a variable called inactiveUser, which will be of type boolean. This will track whether the user is considered inactive or not.

inactiveUser: boolean;
Enter fullscreen mode Exit fullscreen mode

You’re probably keeping track of when the user is successfully authenticated. This is the right time to start watching for when the user becomes idle or not.

if (authenticated) {
  this.idle.watch();
} else {
  this.idle.stop();
}
Enter fullscreen mode Exit fullscreen mode

Now let’s create a private method called handleInactiveUser.

private handleInactiveUser() {
  this.idle.setIdle(300);
  this.idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
  this.idle.setTimeout(15);

  this.handleIdleStart();
  this.handleIdleEnd();
  this.handleTimeoutWarning();
  this.handleTimeout();
}
Enter fullscreen mode Exit fullscreen mode
  • setIdle defines the number of seconds before a user is considered idle. So 300 seconds would be 5 minutes.
  • setInterrupts defines what events will stop a user from being considered idle. We’ll use the default ones like mouse move, key down, etc.
  • setTimeout defines the number of seconds before a user times out. The user will have 15 seconds to take action before they time out.
  • handleIdleStart will listen for when the user is considered idle. We will set inactiveUser to true when this happens.
  • handleIdleEnd will listen for when the user is no longer considered idle. We will set inactiveUser to false when this happens.
  • handleTimeoutWarning will listen for the countdown. We will set inactiveCountdown to this countdown.
  • handleTimeout will listen for when the user is considered timed out. We will log the user out at this point.

Let’s create those 4 methods mentioned above.

private handleIdleStart() {
  this.idle.onIdleStart.subscribe(() => {
    this.inactiveUser = true;
  });
}

private handleIdleEnd() {
  this.idle.onIdleEnd.subscribe(() => {
    this.inactiveUser = false;
  });
}

private handleTimeout() {
  this.idle.onTimeout.subscribe(() => {
    this.inactiveUser = false;
    this.logOut();
  });
}

private handleTimeoutWarning() {
  this.idle.onTimeoutWarning.subscribe(countdown => {
    this.inactiveCountdown = countdown;
  });
}
Enter fullscreen mode Exit fullscreen mode

All that’s left to do is call handleInactiveUser() in ngOnInit.

ngOnInit() {
  this.handleInactiveUser();
}
Enter fullscreen mode Exit fullscreen mode

Access your application and remain inactive for the number of seconds you defined. You should see the alert appear with the countdown. If you take any action the countdown will stop and the alert will disappear. If you time out, you’ll be logged out automatically!


Visit our website at https://nightwolf.dev and follow us on Twitter!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .