51 lines
2.1 KiB
TypeScript
51 lines
2.1 KiB
TypeScript
import { HttpErrorResponse, HttpInterceptorFn } from '@angular/common/http';
|
|
import { inject } from '@angular/core';
|
|
import { AuthService } from '../service/auth.service';
|
|
import { catchError, from, switchMap, throwError } from 'rxjs';
|
|
import { Router } from '@angular/router';
|
|
|
|
export const authInterceptor: HttpInterceptorFn = (req, next) => {
|
|
const authService = inject(AuthService);
|
|
const router = inject(Router);
|
|
const token = authService.accessToken();
|
|
if (token) {
|
|
// first we try with the current token
|
|
return next(
|
|
req.clone({
|
|
headers: req.headers.set('Authorization', `Bearer ${token}`),
|
|
}),
|
|
).pipe(
|
|
catchError((error: HttpErrorResponse) => {
|
|
// if the request with the current token returned 401,
|
|
// try refreshing, then retry the request with the new token
|
|
// for this first scenario, do not retry if we are getting 401 from login or refreshing
|
|
if (
|
|
error.status === 401 &&
|
|
!(error.url?.endsWith('auth/login') || error.url?.endsWith('auth/refresh'))
|
|
) {
|
|
return authService.refresh().pipe(
|
|
switchMap((loginView) => {
|
|
const newToken = loginView.accessToken;
|
|
return next(
|
|
req.clone({
|
|
headers: req.headers.set('Authorization', `Bearer ${newToken}`),
|
|
}),
|
|
);
|
|
}),
|
|
);
|
|
} else if (error.status === 401 && error.url?.endsWith('auth/refresh')) {
|
|
// our refresh token is expired
|
|
// redirect to login page
|
|
return from(router.navigate(['/'])).pipe(
|
|
switchMap(() => throwError(() => error)),
|
|
);
|
|
} else {
|
|
return throwError(() => error);
|
|
}
|
|
}),
|
|
);
|
|
} else {
|
|
return next(req);
|
|
}
|
|
};
|