Implementing an automatic logout feature based on the expiration timestamp of a JWT token

My goal is to have the application automatically log out based on an expiry token.

Angular Client Code:

login(credentials) {
    return this.http.post('http://something/api/login/',
      credentials)
      .map(response => {
        let result = response.json();
        if (result && result.token) {
          localStorage.setItem('token', result.token);
          return true;
        }
        return false;
      });
  }

The token includes an expiry time:

  "exp": 1526016179 // expiry time

I thought of implementing this in the app.component which contains

<router-outlet></router-outlet>
:

ngOnInit() {
    let token = localStorage.getItem('token');
   timer:DateTime = new Date(_JwtHelper.decodeToken(token).exp);
    if (timer && (Date.now() > timer)) {
      logout();       
    }
  }

However, a potential issue with this approach is that it would not logout automatically and would require user activity such as pressing a button to trigger the ngOnInit() function in app.component (which may not be guaranteed to fire every time a button is clicked throughout the website).

The desired functionality is for the application to automatically log out and redirect to the login page once the expiry time is reached.

Answer №1

Implement a timer using setInterval to track the time until the next API call should be made. If the current time surpasses the session expiry time, automatically log out. Whenever a new call is sent to the server, reset the timer.

This functionality can be set up as a dedicated service that can be accessed through the httpInterceptor service.

Answer №2

In order to accomplish this, the user must take a specific action on the UI. I have implemented this process as described below. However, it only occurs when the user initiates a service call. All service calls within my system are routed through this particular method.

public initiateHttpRequest(url, options): Observable<any> {

    if (options.authorizationRequired) {
      if (!options.headers) {
        const token = this.currentUser.token;
        const headers = new Headers();
        headers.append('Access-Control-Allow-Origin', '*');
        headers.append('Content-Type', 'application/json');
        headers.append('Authorization', 'bearer ' + token);
        headers.append('UserName', this.currentUser.username);
        options.headers = headers;
      }
    }

    return this.http.request(url, options).map(this.processData).catch(this.handleErrors.bind(this)).pipe(
      tap( 
        data => {}
        ,
        error => {}
      )
    );

}


private processData(res: Response) {
    const body = res.json();
    return body || {};
}

private handleErrors(error: Response | any) {
    let errorMessage: string;
    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errorMessage = `${error.status} - ${error.statusText || ''} ${err}`;
      if (error.status === 401 || error.status === 403) {
        // Handle logout functionality here
        this.router.navigate(['logout']);

      }
    } else {
      errorMessage = error.message ? error.message : error.toString();
    }
    return Observable.throw(errorMessage);
 }

I believe this solution will be beneficial for others facing similar challenges.

Answer №3

    let decodedToken = JSON.parse(atob(response.jwtToken.split('.')[1]));
    let expirationTime = new Date(decodedToken.exp * 1000);
    let timeUntilExpiration = expirationTime.getTime() - Date.now();
    setTimeout(() => this.logout(strategyName), timeUntilExpiration);

This code snippet utilizes the response.JwtToken as the token obtained after a successful login. It then automatically logs out the user once the token expires by using a timed timeout function.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Starting up a pre-existing Angular project on your local machine

I am completely new to Angular and facing difficulties running an existing project on my machine. Despite conducting numerous tests and following various articles, I still cannot get the project to run. Here is the layout of my project files: https://i.s ...

Customizing npm package within an Angular 13 project

Currently, I am working on an Angular application (v13.3.10) that relies on the ngx-markdown package. Unfortunately, I have encountered several bugs within this package and I am attempting to make edits locally in order to see changes reflected when runnin ...

Confirm that the dependency has been invoked using Sinon

I am currently working on testing whether a dependency has been called or not. Here is an example of my code: export default class vehicle { private builder: CarBuilder; constructor() { this.builder = CreateCar(); <- factory return fake data } crea ...

Adjusting an item according to a specified pathway

I am currently working on dynamically modifying an object based on a given path, but I am encountering some difficulties in the process. I have managed to create a method that retrieves values at a specified path, and now I need to update values at that pa ...

Exploring the ngCookies (AngularJS) functionality within Angular versions 4 and 5

Can you explain how to use $cookies in AngularJS within Angular 4/5? Here's an example using AngularJS: let app = angular.module('myApp', ['ngCookies']); app.controller('MainController', MainController); MainController. ...

What are the steps for transitioning an Angular application from MonoRepo to PolyRepo?

Having created three separate Angular applications with individual workspaces, projects, and repositories, I am able to share modules among them using @angular-architects/module-federation. However, I am facing challenges when it comes to sharing component ...

Creating a task management application using Vue 3 Composition API and Typescript with reactivity

I am in the process of creating a simple todo list application using Vue 3 Composition API and TypeScript. Initially, I set up the function for my component to utilize the ref method to manage the reactivity of user input inserted into the listItems array. ...

How do I bind a div element in Angular 2?

<div *ngFor="let city of israelCitieService.data|mychoosedcities:wordSerched;let i=index" </div> I am trying to find out how to access the length of the array generated by the pipe. The index (i) is only accessible within the div element. Ho ...

Angular router consistently redirecting to the identical module

It's really frustrating me. I've set up 3 basic routes in my app module: routes: Routes = [ { path: '', redirectTo: '/customers', pathMatch: 'full' }, { path: 'customers', loadChildren: './com ...

Unable to utilize SASS variables in Angular from a global file, even though other styles are functioning correctly

After implementing the SASS code in my component's style, it functions correctly. $test-color: pink; div{ background-color: $test-color; } However, when I transfer the definition to styles.scss, the desired outcome is not achieved. I have attempted u ...

The local variable within the Angular constructor is not initialized until the ngOnInit() function is invoked

I am encountering difficulties with making backend calls from Angular. In my component, I am fetching the "category" parameter from the URL as shown below: export class ProductsComponent{ productList = [] category = "" $params; $products ...

Using TypeScript with Redux for Form Validation in FieldArray

My first time implementing a FieldArray from redux-form has been quite a learning experience. The UI functions properly, but there seems to be some performance issues that I need to investigate further. Basically, the concept is to click an ADD button to i ...

Issues with typescript compiler when using React-beautiful-dnd

I recently updated react and react-beautiful-dnd to the newest versions and now I am encountering many type errors in my code: {sortedDimensions.map((dimension: any, index: number) => ( <Draggable key={index} ...

Unable to access member function of Typescript class

I recently started using typescript and encountered an issue while working on a problem. I initially created the following class: export class ModuleInfoContainer extends Array<ModuleInfo> { constructor() { super(); } search(id: number) { ...

The error message "Unable to access property 'open' of an undefined menu" is being displayed in a TypeScript code

I am facing an issue with the action in my menu. For this project, I am using a material menu and icons. The main menu code appears as follows: <mat-menu #rootMenu="matMenu" [overlapTrigger]="false"> <ng-template matMenuContent let-element="ele ...

No response was forthcoming

I have been trying to send a post request to my login endpoint, but I am not receiving any response. Despite thoroughly checking my code, I am unable to figure out why there is no response being sent back. My backend is built using Express in TypeScript. B ...

When merging interfaces and classes, Typescript does not verify property initialization

When creating a class like the following: class Dog { a: string; b: string; c: string; } The TypeScript compiler will throw an error stating that properties a, b, and c are not initialized. However, if we take a different approach like this: i ...

Creating the document.ready function in Angular2 with JQuery

I am seeking assistance to modify the JQuery function so that it can run without the requirement of a button click. Currently, the function only executes when a button is clicked. Code declare var jQuery: any; @Component({ selector: 'home-component ...

Convert a JavaScript variable to a TypeScript interface

In my JavaScript project, I am utilizing TypeScript and JSDOC for code validation against the TS compiler. When analyzing my code, the TS compiler identifies an error in the following snippet: interface IBox { idx: number; } interface IBoxes { ...

When using React with TypeScript, there seems to be an issue where using history.push to change the URL results in rendering the 404 page instead

I have gone through all the previous answers but none of them could solve my problem. I am new to React and currently working on a personal project where I use React with TypeScript, Redux, and Material UI. For some reason, when I try to redirect from ins ...