令牌刷新后的Angular 4 Interceptor重试请求 [英] Angular 4 Interceptor retry requests after token refresh
问题描述
您好我正在尝试通过刷新令牌并重试请求来弄清楚如何实现新的角度拦截器并处理 401未授权的
错误。这是我一直遵循的指南: https:// ryanchenkie.com/angular-authentication-using-the-http-client-and-http-interceptors
Hi I am trying to figure out how implement the new angular interceptors and handle 401 unauthorized
errors by refreshing the token and retrying the request. This is the guide I have been following: https://ryanchenkie.com/angular-authentication-using-the-http-client-and-http-interceptors
我成功缓存了失败的请求并可以刷新令牌,但我无法弄清楚如何重新发送以前失败的请求。我也想让这个与我目前正在使用的解析器一起工作。
I am successfully caching the failed requests and can refresh the token but I cannot figure out how to resend the requests that previously failed. I also want to get this to work with the resolvers I am currently using.
token.interceptor.ts
token.interceptor.ts
return next.handle( request ).do(( event: HttpEvent<any> ) => {
if ( event instanceof HttpResponse ) {
// do stuff with response if you want
}
}, ( err: any ) => {
if ( err instanceof HttpErrorResponse ) {
if ( err.status === 401 ) {
console.log( err );
this.auth.collectFailedRequest( request );
this.auth.refreshToken().subscribe( resp => {
if ( !resp ) {
console.log( "Invalid" );
} else {
this.auth.retryFailedRequests();
}
} );
}
}
} );
authentication.service.ts
authentication.service.ts
cachedRequests: Array<HttpRequest<any>> = [];
public collectFailedRequest ( request ): void {
this.cachedRequests.push( request );
}
public retryFailedRequests (): void {
// retry the requests. this method can
// be called after the token is refreshed
this.cachedRequests.forEach( request => {
request = request.clone( {
setHeaders: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${ this.getToken() }`
}
} );
//??What to do here
} );
}
上面的retryFailedRequests()文件是我无法弄清楚的。如何重新发送请求并在重试后通过解析程序将其提供给路由?
The above retryFailedRequests() file is what I can't figure out. How do I resend the requests and make them available to the route through the resolver after retrying?
如果有帮助,这是所有相关代码: https://gist.github.com/joshharms/00d8159900897dc5bed45757e30405f9
This is all the relevant code if that helps: https://gist.github.com/joshharms/00d8159900897dc5bed45757e30405f9
推荐答案
我的最终解决方案。使用并行请求。
My final solution. Works with parallel requests.
export class AuthInterceptor implements HttpInterceptor {
authService;
refreshTokenInProgress = false;
tokenRefreshedSource = new Subject();
tokenRefreshed$ = this.tokenRefreshedSource.asObservable();
constructor(private injector: Injector, private router: Router, private snackBar: MdSnackBar) {}
addAuthHeader(request) {
const authHeader = this.authService.getAuthorizationHeader();
if (authHeader) {
return request.clone({
setHeaders: {
"Authorization": authHeader
}
});
}
return request;
}
refreshToken() {
if (this.refreshTokenInProgress) {
return new Observable(observer => {
this.tokenRefreshed$.subscribe(() => {
observer.next();
observer.complete();
});
});
} else {
this.refreshTokenInProgress = true;
return this.authService.refreshToken()
.do(() => {
this.refreshTokenInProgress = false;
this.tokenRefreshedSource.next();
});
}
}
logout() {
this.authService.logout();
this.router.navigate(["login"]);
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<any> {
this.authService = this.injector.get(AuthService);
// Handle request
request = this.addAuthHeader(request);
// Handle response
return next.handle(request).catch(error => {
if (error.status === 401) {
return this.refreshToken()
.switchMap(() => {
request = this.addAuthHeader(request);
return next.handle(request);
})
.catch(() => {
this.logout();
return Observable.empty();
});
}
return Observable.throw(error);
});
}
}
这篇关于令牌刷新后的Angular 4 Interceptor重试请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!