Here is the code snippet I've been working on:
AuthenticationService
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ActivatedRoute, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
public currentUser: string
constructor(
private http: HttpClient,
private route: ActivatedRoute,
private router: Router,
) { }
login(username:string, password:string){
return this.http.post<any>('http://localhost:8000/api/token/', {username: username, password: password})
.pipe(
map(data => {
localStorage.setItem('access_token', data.access)
localStorage.setItem('refresh_token', data.refresh)
})
)
}
logout(){
localStorage.removeItem('access_token')
localStorage.removeItem('refresh_token')
}
getJWToken(){
return localStorage.getItem('access_token')
}
getRefreshToken(){
return localStorage.getItem('refresh_token')
}
refreshToken(){
let refreshToken : string = localStorage.getItem('refresh_token');
return this.http.post<any>('http://localhost:8000/api/token/refresh/', {"refresh": refreshToken}).pipe(
map(data => {
localStorage.setItem('access_token', data.access)
},
error => {
this.router.navigate(['/login']);
}
)
)
}
}
TokenInterceptor
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, first, switchMap } from 'rxjs/operators';
import {AuthenticationService} from '../services/authentication.service'
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(public authService : AuthenticationService ) {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
return next.handle(this.addToken(request, localStorage.getItem('access_token')))
.pipe(catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 401) {
return this.refreshToken()
.pipe(switchMap(
data => next.handle(this.addToken(request, localStorage.getItem('access_token')))
))
} else {
return throwError(error);
}
}));
}
private addToken(request: HttpRequest<any>, token: string) {
return request.clone({
setHeaders: {
'Authorization': `Bearer ${token}`
}
});
}
private refreshToken(){
return this.authService.refreshToken()
}
}
I'm facing a challenge with error handling in my AuthenticationService's refreshToken method. How can I properly catch errors, particularly when a 401 error occurs, and redirect to the login page? Any suggestions on how to solve this issue would be greatly appreciated.