UNPKG

jangular-cli

Version:

A powerful CLI tool for rapidly bootstrapping Angular 17 & Spring Boot (Java 21) applications with integrated security, services, and enterprise-ready best practices.

88 lines (79 loc) 2.69 kB
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError, BehaviorSubject } from 'rxjs'; import { catchError, filter, take, switchMap } from 'rxjs/operators'; import { Router } from '@angular/router'; import { AuthService } from './services/auth/auth.service'; @Injectable() export class TokenInterceptor implements HttpInterceptor { private isRefreshing = false; private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null); constructor( private authService: AuthService, private router: Router ) { } intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { // Add auth token to requests if (this.authService.isAuthenticated()) { request = this.addToken(request, this.authService.getAccessToken()!); } return next.handle(request).pipe( catchError(error => { if (error instanceof HttpErrorResponse && error.status === 401) { return this.handle401Error(request, next); } else { return throwError(() => error); } }) ); } private addToken(request: HttpRequest<any>, token: string) { return request.clone({ setHeaders: { 'Authorization': `Bearer ${token}` } }); } private handle401Error(request: HttpRequest<any>, next: HttpHandler) { if (!this.isRefreshing) { this.isRefreshing = true; this.refreshTokenSubject.next(null); const refreshToken = localStorage.getItem('refresh_token'); if (refreshToken) { return this.authService.refreshToken(refreshToken).pipe( switchMap((token: any) => { this.isRefreshing = false; this.refreshTokenSubject.next(token); return next.handle(this.addToken(request, token.accessToken)); }), catchError((err) => { this.isRefreshing = false; this.authService.logout(); this.router.navigate(['/auth/login']); return throwError(() => err); }) ); } else { // No refresh token available, redirect to login this.isRefreshing = false; this.authService.logout(); this.router.navigate(['/auth/login']); return throwError(() => new Error('No refresh token available')); } } else { return this.refreshTokenSubject.pipe( filter(token => token != null), take(1), switchMap(jwt => { return next.handle(this.addToken(request, jwt.accessToken)); }) ); } } }