如何使Angular 5 httpClient订阅等待拦截器响应

时间:2018-04-10 14:48:16

标签: httpclient angular5 interceptor subscription

简短版:---

如何制作(http).post()。subscription()等待截获的响应而不是401响应?

---- LONG版本----

在我的userHttpService中,我有一个从组件中调用的函数(使用HttpClient):

 findCostumer(companyName: string){
    let data = {companyName: companyName}
    return this.http.post('http://localhost/angular2/findCostumer.php', JSON.stringify(data),{responseType:'text'})
}

为了能够访问findCostumer.php,我必须登录,因为我在Interceptor中发送令牌In标头。

const cloned = req.clone({
                headers: req.headers.set('Authorization', localStorage.getItem('jwt')).
                set('refreshToken', localStorage.getItem('refreshToken'))                 
        })

哪种方法正常。

但是如果JWT过期,我想用我持久的刷新令牌刷新该令牌。 这是我的全部代码:

intercept(req:HttpRequest<any>, next:HttpHandler ): Observable<HttpEvent<any>>{
    if(localStorage.getItem('jwt') && localStorage.getItem('refreshToken')){
        const cloned = req.clone({
                headers: req.headers.set('Authorization', localStorage.getItem('jwt')).
                set('refreshToken', localStorage.getItem('refreshToken'))                 
        })
       let userhttpservice = this.injector.get(UserHttpService);

        return next.handle(cloned).catch(er=>{
            if(!this.update && er.status == 401)
            {
                 userhttpservice.refreshToken().mergeMap(re=>{
                    console.log(re)
                    this.update = false
                    let json = JSON.parse(re);
                    localStorage.setItem('jwt', json['jwt'])
                    localStorage.setItem('refreshToken', json['refreshToken'])
                    let cloned3 = req.clone({
                        headers: req.headers.set('Authorization', localStorage.getItem('jwt')).
                        set('refreshToken', localStorage.getItem('refreshToken'))  

                     })
                    return next.handle(cloned3)
                }).subscribe();
                //return next.handle(cloned)
                this.update = true;     

            }
            return Observable.throw('')
        })      
    }
    else
        return next.handle(req) 
}
userHtppService中的

refreshToken-function:

 refreshToken(){
    let data =  {'token':localStorage.getItem('refreshToken')};
    return this.Http.post('http://localhost/angular2/refreshToken.php', JSON.stringify(data),{responseType:'text'})  
}

哪个也行。然而。关于findCostumer.php的订阅它只获得401响应。不是刷新令牌后请求的那个。我猜它与catch() - 运算符有关,返回Observable.throw(&#39;&#39;),订阅作为&#34; final&#34;响应,忽略了一个新的事实,即我在刷新令牌后授予了访问权限。 我如何make.subscription()等待200页的状态?

1 个答案:

答案 0 :(得分:0)

我想可以做到以下几点(但是在拦截器中调用HttpClient被认为是不好的做法,因为它可能会创建循环调用:

import {HttpClient, HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Injectable} from "@angular/core";
import {Observable} from "rxjs/Rx";
import {LoginModalComponent} from "@app/shared/components/login-modal/login-modal.component";
import {BsModalService} from "ngx-bootstrap";
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';

@Injectable()
export class HttpAuthInterceptor implements HttpInterceptor {

  constructor(private httpClient: HttpClient) {
  }

  private isAuthError(error: any): boolean {
    return error instanceof HttpErrorResponse && error.status == 401;
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const intialRequest = request.clone();

    return next.handle(request)
      .catch((error) => {
        if (!this.isAuthError(error)) {
          return Observable.throwError(error);
        }

        this.httpClient.get('/refresh-token').subscribe(res => {
          console.log('Token refreshed');

          // repeating initial request
          return next.handle(intialRequest).do(res => res);
        });
  }
}