如果存在身份验证错误,我正在尝试使拦截器刷新用户令牌。我在这里问这个问题是因为,即使有一些教程和其他问题,我也无法使之工作。
这是我的拦截功能:
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('===== Intercept =====');
console.log(req);
return next.handle(req).pipe(
catchError((err: any) => {
console.log(err);
this.refreshToken().subscribe( resolve => {
console.log('RESOLVE');
// clone the original request
if (resolve) {
console.log('REQ REPEAT');
let headers = new HttpHeaders({
'Content-Type': 'application/json'
});
if (this.appState.token !== null) {
headers = headers.set('Authorization', 'Bearer ' + this.appState.token);
}
const authReqRepeat = req.clone(
{headers: headers}
);
console.log('NEW TOKEN : Bearer ' + this.appState.token);
console.log(authReqRepeat);
// resend the request
return next.handle(authReqRepeat);
} else {
return next.handle(req);
}
}, error => {
console.log('ERROR');
return throwError(error);
});
}),
);
}
refreshToken函数向我返回是或否的答案(如果刷新正常,则为true)。
所以我的第一个问题是关于克隆请求标头的,我尝试了多个可能的方法放置它们,但是最后我的克隆请求上仍然没有标头(如果我不尝试添加一个原始请求标头,则有原始请求标头新的)。
下一个问题也与请求有关,当我的新请求与next.handle
一起发送时(我没有关于此请求的任何日志),并且没有任何内容返回给我的应用程序,因此我的组件正在等待永远不会出现的答案。
第三个问题是关于catchError的,我在(err : any)
TS2345: Argument of type '(err: any) => void' is not assignable to parameter of type '(err: any, caught: Observable<HttpEvent<any>>) => ObservableInput<{}>'. Type 'void' is not assignable to type 'ObservableInput<{}>'.
我对可观察性并不十分满意,但是如果在调用return throwError(error);
之后添加refreshToken
,错误就会消失,但是我有一个无限循环。
答案 0 :(得分:0)
第一个问题,请尝试使用此问题代替附加集:
const headers = new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.appState.token
});
第二个问题,因为您仅使用next.handle(authReqRepeat)。而且没有订阅者,因此它无法运行,您可以尝试以下操作:
http.request(authReqRepeat).subscribe(()=>{})
最后一个问题,在“ tap”管道可观察到的内部使用错误:
next.handle(req).pipe(
tap((res) => return of(res),(error) => {doSomething(error); return of(error)})
);
对于无限循环,这是因为您用自身拦截的相同过程重复处理请求,因此请尝试一些方法来跳过内部请求,如下所示:
if (this.reqList.indexOf(req)){ return handle.next(req)} and then ...