I have an Angular v19
project.
I have the following AuthInterceptor
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private isRefreshing = false;
constructor(private authService: AuthService) {
console.log('AuthInterceptor constructed'); // 🟢 Debugging log
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('AuthInterceptor triggered');
let accessToken = localStorage.getItem('accessToken');
console.log('accessToken:', accessToken);
if (accessToken) {
req = this.addToken(req, accessToken);
}
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401 && !this.isRefreshing) {
return this.handle401Error(req, next);
}
return throwError(() => error);
})
);
}
private handle401Error(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.isRefreshing = true;
return this.authService.refreshToken().pipe(
switchMap((response: LoginResponse) => {
this.isRefreshing = false;
return next.handle(this.addToken(req, response.accessToken));
}),
catchError(error => {
this.isRefreshing = false;
this.authService.logout();
return throwError(() => error);
})
);
}
private addToken(req: HttpRequest<any>, token: string): HttpRequest<any> {
return req.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
}
}
The goal for this AuthInterceptor
is to check for accessToken, if exists, append to headers before any request is made.
I have the following ApiService
,
@Injectable({
providedIn: 'root'
})
export class ApiService {
private baseUrl = environment.apiBaseUrl;
constructor(private http: HttpClient) { }
get<T>(endpoint: string) {
return this.http.get<T>(this.baseUrl + endpoint);
}
post<T>(endpoint: string, data: any) {
return this.http.post<T>(this.baseUrl + endpoint, data);
}
put<T>(endpoint: string, data: any) {
return this.http.put<T>(this.baseUrl + endpoint, data);
}
delete<T>(endpoint: string) {
return this.http.delete<T>(this.baseUrl + endpoint);
}
}
The AuthInterceptor
is registered within app.config.ts
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
importProvidersFrom(ReactiveFormsModule),
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } // Here!!!!
]
};
Within my component I call
async ngOnInit() {
try {
const response = await firstValueFrom(this.teamService.getTeams());
console.log(response);
} catch (error) {
console.log(error);
}
}
Which calls my TeamsService
:
getTeams(): Observable<ApiResponse<TeamDetail>> {
return this.apiService.get<ApiResponse<TeamDetail>>(`api/Team/all`);
}
But no matter what I try, the AuthInterceptor
isn't registered, nor is the accessToken added to the headers.. I have search the web, but keep hitting bricks walls, can someone spot what I'm doing wrong here?
When using auth interceptor configuration object { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
for interceptor, we have to specify withInterceptorsfromDI
within provideHttpClient
so that the interceptor is recognized.
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withInterceptorsFromDi()), // <- notice!
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
importProvidersFrom(ReactiveFormsModule),
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } // Here!!!!
]
};