【问题标题】:Angular: Adding bearer token in interceptorAngular:在拦截器中添加不记名令牌
【发布时间】:2021-03-22 01:18:11
【问题描述】:

我正在使用 Angular + AWS Cognito

我能够登录并需要添加 cognito Bearer 令牌

@Injectable({
providedIn: 'root',
})
export class InterceptorService implements HttpInterceptor {
constructor(public loaderService: LoaderService, private router: Router) { }

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this.getToken().pipe(
        mergeMap((token) => {
            request = request.clone(
                {
                    setHeaders: { Authorization: `Bearer ${token}` }
                });

            return next.handle(request);
        })
    );
}

getToken() {
    return from(
        new Promise((resolve, reject) => {
            Auth.currentSession().then((session) => {
                if (!session.isValid()) {
                    resolve(null);
                } else {
                    resolve(session.getIdToken().getJwtToken());
                }
            }).catch(err => { return resolve(null) });
        })
    );
}
}

这段代码运行良好,问题是这里如何处理HttpResponse?

我尝试了以下代码,但没有成功,请求没有Bearer token

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
            tap(
            (event) => {
                if (event instanceof HttpResponse) {
                    if (event.status !== 200) {
                        console.log('Response', event.status);
                    }
                } else {
                    return this.getToken().pipe(
                       mergeMap((token) => {
                            request = request.clone(
                                {
                                    setHeaders: { Authorization: `Bearer ${token}` }
                                });

                            return next.handle(request);
                        })
                    );
                }
            },
            (error) => {
                 // to handle errors
            }
        )
}

【问题讨论】:

  • 请查看stackblitzDemo Link的链接。希望对您有所帮助。

标签: angular angular-http-interceptors


【解决方案1】:

据我所知tap 仅在没有错误时运行。如果您希望您的函数在错误时运行,您必须在管道中使用catchError()

【讨论】:

    【解决方案2】:

    tap 是做副作用的操作符,你不能只从回调中返回 observable,它不会被订阅。发送原始请求并在失败时使用令牌重试的逻辑也有点奇怪。我相信您应该为每个请求添加令牌。

    intercept(...) {
      return this.sendWithToken(request).pipe(
        catchError(error => error.status === 401 ? this.sendWithToken(request) : throwError(error)) // try one more time if return code is 401 
      );
    }
    
    sendWithToken(request: ...) {
      return this.getToken().pipe(
        mergeMap(token => addToken(request)),
        mergeMap(authedRequest => next.handle(authedRequest)),
      );
    }
    

    还可以改进 getToken 代码,因为如果你已经有一个承诺,你就不需要创建承诺

    getToken() {
        return from(
            Auth.currentSession().then((session) => {
                if (!session.isValid()) {
                    return null;
                } else {
                    return session.getIdToken().getJwtToken();
                }
            }).catch(err => null);
        );
    }
    

    【讨论】:

      【解决方案3】:

      我用以下拦截器代码解决了这个问题:

      intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
          return this.getToken().pipe(
              mergeMap((token) => {
                  request = request.clone(
                      {
                          headers: request.headers.set('Authorization', `Bearer ${token}`)
                      });
      
                  return next.handle(request).pipe(
                      tap(evt => {
                            // modify here
                      }),
                      catchError((error: any) => {
                          if (error && error.status) {
                              if (error.status == 401) {
                                  this.router.navigate(['/']);
                              }
                          } else {
                              return throwError(error);
                          }
                      })
                  )
              })
          );
      }
      
      getToken() {
          return from(
              Auth.currentSession().then((session) => {
                  if (!session.isValid()) {
                      return null;
                  } else {
                      return session.getIdToken().getJwtToken();
                  }
              }).catch(err => null)
          );
      }
      

      【讨论】:

        猜你喜欢
        • 2019-10-22
        • 2018-12-29
        • 1970-01-01
        • 2020-05-07
        • 2021-11-12
        • 1970-01-01
        • 2019-03-28
        • 2017-12-31
        • 2017-12-26
        相关资源
        最近更新 更多