我有一个拦截器,可以在令牌过期时捕获服务器错误。然后,拦截器向api请求刷新的令牌。成功后,拦截器将再次发送http请求。发生错误时,拦截器会删除本地存储,并应重定向到登录页面。
现在我有一个带有canDeactivate Guard的页面。所以我想签入canDeactivate Guard令牌是否有效。如果无效,我想向API请求刷新的令牌。成功后,我不想离开页面。发生错误时,我要注销用户并重定向到登录页面。
// canDeactivateGuard
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
@Injectable({
providedIn: 'root',
})
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
// component
canDeactivate(): Observable<boolean> | boolean {
if (!this.authService.isTokenValid()) {
// here i want to ask the api for a new token
// on error of api I want to redirect the user to login page
// and don't want to show a modal
return this.authService.refreshToken().pipe(
map(res => {
console.log('test');
return false;
}),
catchError(err => {
console.log('test error');
return of(true);
})
);
}
if (Object.is(this.testForm.get('text').value, this.oldText)) {
this.modalService.hide(1);
return true;
} else {
this.modalRef = this.modalService.show(this.modalTemplate);
return false;
}
}
// AuthService
public refreshToken(): Observable<Token> {
return this.http.post<{ data: any }>(`${environment.apiUrl}/auth/refresh`, {}).pipe(
map(({ data }): any => {
const apiToken = this.tokenAdapter.adapt(data);
this.setJwtToken(apiToken);
this.currentTokenSubject.next(apiToken);
return apiToken;
})
);
}
我不知道如何更改从api捕获错误的代码,以及如何重定向用户。 canDeactivate方法的map()和catchError()中的console.logs都不会被调用。
答案 0 :(得分:0)
refreshToken应该遵循以下格式,这将很有帮助
return this.http.get(`${environment.apiUrl}/auth/refresh`, {
}).pipe(
map(({ data }): any => {
const apiToken = this.tokenAdapter.adapt(data);
this.setJwtToken(apiToken);
this.currentTokenSubject.next(apiToken);
return apiToken;
}),
catchError(() => {
return of(false);
}));
然后使用canDeactivate方法
// component
canDeactivate(): Observable<boolean> | boolean {
if(!this.authService.isTokenValid()) {
// here i want to ask the api for a new token
// on error of api I want to redirect the user to login page
// and don't want to show a modal
return this.authService.refreshToken().pipe(
map(res => {
if (!res) {
console.log('test error');
return true;
}
console.log('test');
return false;
})
);
}
if (Object.is(this.testForm.get('text').value, this.oldText)) {
this.modalService.hide(1);
return true;
} else {
this.modalRef = this.modalService.show(this.modalTemplate);
return false;
}
}