在Angular应用程序中,很多时候需要在HTTP请求中添加JWT令牌。为了实现这个功能,可以使用拦截器来在每个请求中添加JWT令牌。但是,JWT令牌的有效期有限,因此我们需要通过异步操作在过期时刷新令牌。
以下是一种正确处理JWT令牌刷新的方法,可以在拦截器中使用。首先,我们需要创建一个名为TokenInterceptor的拦截器,并将其添加到providers数组中。
import { Injectable } from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpErrorResponse
} from '@angular/common/http';
import { Observable, BehaviorSubject, throwError } from 'rxjs';
import { catchError, filter, take, switchMap } from 'rxjs/operators';
import { AuthService } from '../services/auth.service';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject = new BehaviorSubject(null);
constructor(public authService: AuthService) {}
intercept(request: HttpRequest, next: HttpHandler): Observable> {
if (this.authService.getAccessToken()) {
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, token: string) {
return request.clone({
setHeaders: {
'Authorization': `Bearer ${token}`
}
});
}
private handle401Error(request: HttpRequest, next: HttpHandler) {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
return this.authService.refreshToken().pipe(
switchMap((newToken: any) => {
this.isRefreshing = false;
this.refreshTokenSubject.next(newToken.access_token);
return next.handle(this.addToken(request, newToken.access_token));
}),
catchError(err => {
this.isRefreshing = false;
this.authService.logout();
return throwError(err);
})
);
} else {
return this.refreshTokenSubject.pipe(
filter(token => token != null),
take(1),
switchMap(token => {
return next.handle(this.addToken(request, token));
})
);
}
}
}
在上面的代码中