角度刷新令牌拦截器

时间:2019-02-15 08:11:43

标签: angular httprequest angular-http angular-http-interceptors

如果存在身份验证错误,我正在尝试使拦截器刷新用户令牌。我在这里问这个问题是因为,即使有一些教程和其他问题,我也无法使之工作。

这是我的拦截功能:

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,错误就会消失,但是我有一个无限循环。

1 个答案:

答案 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 ...