如何在Angular HttpInterceptor中使用异步HTTP请求

时间:2019-12-04 08:50:45

标签: javascript angular async-await angular-http-interceptors

我使用Angular 7创建了一个HTTP拦截器来处理Oauth2令牌,因此需要一个http请求来获取令牌并将其添加到每个http请求标头中。

我的解决方案:

  1. localStorage获取令牌。
  2. 如果它为null或已过期,则从后端获取令牌。
  3. 将令牌设置为localStorage并设置到期日期。

我的问题是为什么拦截器总是在获取令牌之前返回值。

请参阅以下代码: auth-interceptor.ts

import {Injectable} from "@angular/core";
import {
  HttpEvent,
  HttpHandler,
  HttpHeaders,
  HttpInterceptor,
  HttpRequest
} from "@angular/common/http";
import {Observable, throwError} from "rxjs";
import {CommonService} from "../../services/common/common.service";
import {catchError} from "rxjs/operators";

@Injectable()
export class AuthInterceptor implements HttpInterceptor{

  constructor(private commonService: CommonService) {
  }

  private localDate: Date = new Date();

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    if (req.url.includes('/token')){
      return next.handle(req);
    }
    // 1. get token from localstorage
    let user = localStorage.getItem('token');
    // 2.  1>if expired or null, call get token& save into ls
    if (user && this.validDate()) {
      let userObj = JSON.parse(user);
      let header: HttpHeaders = new HttpHeaders(userObj);
      let request = req.clone({headers: header});
      return next.handle(request).pipe(catchError(err => {
        if (err.status === 401 || err.status === 403) {
          localStorage.removeItem('token');
        }
        return throwError(err);
      }));
    } else {
      return Observable.fromPromise(this.handleAccess(req,next));
    }
  }

  private async handleAccess(request: HttpRequest<any>, next: HttpHandler): Promise<HttpEvent<any>> {
    let token = await this.getToken();
    let header: HttpHeaders = new HttpHeaders(JSON.parse(token));
    let changedRequest = request.clone({headers: header});
    return next.handle(changedRequest).toPromise();
  }

  getToken(): Promise<any>{
    return new Promise((resolve, reject)=>{
      this.commonService.getToken().subscribe(token=>{
        this.localDate = new Date();
        localStorage.setItem('token', JSON.stringify(token));
        resolve(token);
      })
    })
  }

  validDate(): boolean{
    return new Date().valueOf() - this.localDate.valueOf() < 3599 * 1000;
  }
}

getToken()是一个简单的http请求(HttpClient)。

0 个答案:

没有答案