代码之家  ›  专栏  ›  技术社区  ›  Tavish Aggarwal

刷新angular 5中的访问令牌时出现问题

  •  1
  • Tavish Aggarwal  · 技术社区  · 7 年前

    如果用户出现未经授权的错误,我想刷新令牌。我正试图在拦截器中处理这个问题。代码如下:

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
          return next.handle(req).do((event: HttpEvent<any>) => {
          if (event instanceof HttpResponse) {
          }
        }, (err: any) => {
          if (err instanceof HttpErrorResponse) {
            if (err.status === 401) {
              fn.refreshToken(req, next);
    
            }
          }
        });
      }
    

    我有函数refreshToken,我试图调用API来刷新令牌:

    refreshToken(req, next) {
        const headers = new HttpHeaders()
            .set('Content-Type', 'application/x-www-form-urlencoded');
    
        const body = new HttpParams()
          .set('refresh_token', localStorage.getItem('refreshToken'));
         this._http.post('/refreshtoken',  body.toString(), {headers}).subscribe(
           (data) => {
             const header = `Bearer ${(<any>data).accessToken}`;
            const newRequest = req.clone({ headers: req.headers.set('Authorization',  header)});
            return next.handle(newRequest);
    
           }),
            (err) => {
              console.log(err);
            }
    
      }
    

    但上述代码的问题是,我无法调用克隆的请求。只有在我调用subscribe方法时才会触发该请求。如下所示:

     return next.handle(newRequest).subscribe();
    

    如果令牌过期,请调用服务刷新令牌并重新发送失败的原始请求。此外,调用失败的原始请求的subscribe方法。

    请让我知道我的方法是否正确。

    如果是的话,那么我在这里错过了什么。

    1 回复  |  直到 7 年前
        1
  •  1
  •   martin    7 年前

    拦截器必须返回一个可观察的,并且可以调用 next.handle(req) 所以我想你可以打电话 下一个手柄(req) 两次但更好、更多的“Rx”解决方案是使用 catch 运算符并合并原始可观测源。你还需要换衣服 refreshToken 要返回一个可观察的标记,您可能需要将新标记存储为 do() .

    refreshToken(...): Observable<any> {
      return this._http.post('/refreshtoken', ...)
        .do(/* save token here */);
    }
    
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      return next.handle(req)
        .catch((err, source) => {
          if (err instanceof HttpErrorResponse && err.status === 401) {
            return this.refreshToken(...)
              .concatMap(() => next.handle(req /* ... or updated req */ ));
              // or you could use .concatMap(() => source) to trigger the same request again
          }
          throw err;
        })
    }