[英]angular 2 http exception handler and jwt refresh
當遇到某個異常時,我正在嘗試刷新JWT令牌,當它是另一個異常時,我的ErrorHandler應該處理它們。
我有一段代碼,其中一個代碼可用於令牌刷新,而另一段代碼可用於異常處理程序,但我只是無法以一種有效的方式組合它們。
問題是我無法拋出異常並以可觀察的方式用我的ErrorHandler捕獲它。
這是我可以用來刷新令牌的代碼。 如果失敗,它將檢查錯誤代碼是否為token_expired
,如果失敗,它將刷新令牌token_expired
試請求。
export class HttpErrorService extends Http {
constructor(backend: XHRBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs, disableRefresh = false): Observable<Response> {
return super.request(url, options).catch((error: Response) => {
// Refresh token on token_expired exception.
if (!disableRefresh && error.status === 401 && error.json().error.code === 'token_expired') {
return this.renewToken().flatMap((response) => {
const res = response.json();
// Replace the token in storage.
localStorage.setItem('__token', res.data.token);
// Replace request the token with the new one.
if (url instanceof Request) {
url.headers.set('Authorization', 'Bearer ' + res.data.token);
} else if (options) {
options.headers.set('Authorization', 'Bearer ' + res.data.token);
}
// To prevent a loop disable refreshing at the next request.
return this.request(url, options, true);
});
}
// Here I want to throw the exception.
// I need to be able to catch it with my exception handler.
// throw error; doesn't work.
return Observable.throw(error);
});
}
private getBaseUrl(): string {
return environment.base_uri;
};
renewToken(): Observable<Response> {
const headers = new Headers();
headers.append('Authorization', 'Bearer ' + localStorage.getItem('__token'))
return this.post(this.getBaseUrl() + '/auth/refresh', {}, {headers: headers});
}
}
上面唯一的壞處是我無法在異常處理程序中捕獲異常。
以下代碼可以引發ErrorHandler可以捕獲的異常。 但我不知道如何在一次通話中刷新令牌...
export class HttpErrorService extends Http {
constructor(backend: XHRBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs, disableRefresh = false): Observable<Response> {
return Observable.create(observer => {
super.request(url, options).subscribe(
res => observer.next(res),
err => {
if (!disableRefresh && err.status === 401 && err.json().error.code === 'token_expired') {
// I can't return this.renewToken()...
}
observer.error(err);
throw new HttpException(err); // this is getting catched by the ErrorHandler
},
() => observer.complete);
});
}
private getBaseUrl(): string {
return environment.base_uri;
};
renewToken(): Observable<Response> {
const headers = new Headers();
headers.append('Authorization', 'Bearer ' + localStorage.getItem('__token'))
return this.post(this.getBaseUrl() + '/auth/refresh', {}, {headers: headers});
}
}
我的錯誤處理程序僅包含console.log()
。
https://angular.io/api/core/ErrorHandler
我該如何工作?
幾個小時后,我終於找到了解決方案!
export class HttpErrorService extends Http {
constructor(backend: XHRBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs, disableRefresh = false): Observable<Response> {
return Observable.create(observer => {
super.request(url, options).retryWhen(attempts => this.retryRequest(attempts)).catch((error: Response) => {
// Refresh token on token_expired exception.
if (!disableRefresh && error.status === 401 && error.json().error.code === 'token_expired') {
return this.renewToken().flatMap((response) => {
const res = response.json();
// Replace the token in storage.
localStorage.setItem('__token', res.data.token);
// Replace request the token with the new one.
if (url instanceof Request) {
url.headers.set('Authorization', 'Bearer ' + res.data.token);
} else if (options) {
options.headers.set('Authorization', 'Bearer ' + res.data.token);
}
// To prevent a loop disable refreshing at the next request.
return this.request(url, options, true);
});
}
throw Observable.throw(error);
}).subscribe(
res => observer.next(res),
err => {
observer.error(err);
throw new HttpException(err);
}
);
});
}
private getBaseUrl(): string {
return environment.base_uri;
};
renewToken(): Observable<Response> {
const headers = new Headers();
headers.append('Authorization', 'Bearer ' + localStorage.getItem('__token'))
return this.post(this.getBaseUrl() + '/auth/refresh', {}, {headers: headers});
}
retryRequest(attempts: any) {
let count = 0;
return attempts.flatMap(error => {
return ++count >= 3 ? Observable.throw(error) : Observable.timer(count * 1000);
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.