I have access token and refresh token for an API. One user can have different refresh tokens for different API, and I don't know how to manage access token when access token is expired.
For now I solve it like this, but seems like it is a complex solution because I have to add it to all functions and when refresh token is expired It can't handle it. updateAccessToken function sends request to endpoint, get new access token and update it on state management system.
getAllBuckets(account: GetAllBucket){
const {project, accessToken} = account
const qs = new URLSearchParams({project})
return this.http.get(`${this.urlGoogleStorage}?${qs.toString()}`, { headers: {Authorization: `Bearer ${accessToken}`}}).pipe(
catchError((error) => {
if(error.status == 401) this.auth.updateAccessToken(account);
return throwError(() => error)
})
)
}
Can anybody suggest better solution?
Angular has a feature called Http interceptor for this kind of use cases. Using interceptor you can intercept every request from your angular project. It works like a middleware in http calls.
You can create an interceptor like this,
@Injectable({
providedIn: 'root',
})
export class TokenInterceptorService implements HttpInterceptor {
constructor(private auth: TokenService) {}
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
let token = this.auth.getToken();
// Attach your token to every request
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
});
return next.handle(request).pipe(
catchError(res=>{
if(res instanceof HttpErrorResponse && res.status===401){
// You can write your desired token update logic here
let newToken = this.auth.updateAccessToken(account);
request = request.clone({
setHeaders: {
Authorization: `Bearer ${newToken}`,
},
});
// === End section ==
next.handle(request);
}else{
return throwError(res);
}
})
);
} }
After that you have to provide this interceptor on the root module,
@NgModule({
declarations: [..],
imports: [
...
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: TokenInterceptorService ,
multi: true,
},
],
Now every http call you made from a service which is provided in root will be go through this interceptor. You can modify request according to your needs in this interceptor service,
you can find the documentation here: https://angular.io/api/common/http/HttpInterceptor