HttpInterceptor + Angular 5和HttpClient

时间:2017-11-30 11:28:09

标签: angular

我有问题,我想在我的API HTTP请求中添加Token。为获取我的令牌,我发出http请求。 这是我的代码:

HttpInterceptor:

@Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(private inj: Injector) { }

getRequestWithAuthorization(request: HttpRequest<any>):any
{
    let token:String ;
    this.inj.get(CnafUserService).getTokenJWTObservable().subscribe( data => { 
        token = data ;
        request = request.clone({ headers: request.headers.set('Authorization', `${token}`) });
        return request;
    })
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    //Ajout du header Authorization
    if (request && request.url.match("^/api/"))
    {
        //Here the problem, request is null because the call is asynchronous
        request = this.getRequestWithAuthorization(request,next);
        return next.handle(request);
    }
    return next.handle(request);
}

}

服务:

   getTokenJWTObservable(): Observable<any> {
        return this.http.get(this.urlServletJwt);
    }

如何,我要求获取令牌,然后返回带标题的请求?

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

我还没有尝试过这个解决方案,所以如果我在这里错了,请随时纠正我。

问题似乎是在你的getRequestWithAuthorization功能中你没有返回任何东西,尽管你正试图从那里得到一些东西。

getRequestWithAuthorization(request: HttpRequest<any>):any
{
    let token:String ;
    this.inj.get(CnafUserService).getTokenJWTObservable().subscribe( data => { 
        token = data ;
        request = request.clone({ headers: request.headers.set('Authorization', `${token}`) });
        // this will only return the request to the subscribe call
        // but not the calling function itself
        return request;
    })
    // no return value here
}

您只是从订阅函数返回请求,但作为内部函数(至少是我对它的理解),请求不会再被传递。目前,您没有对请求做任何事情。

This question here与您有类似的问题。我们最终想要返回的是next.handle(request)这是一个可观察的。在我们能够做到这一点之前,我们必须对您的令牌执行请求,这也是一个可观察的请求。要在最后返回正确的observable,我们使用switchMap运算符。我们将获取令牌,使用可观察的结果来更改请求并返回the next.handle(request)。我认为它应该是这样的。

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if(request && request.url.match("^/api/")) {
        // we have to return this block which after the flatMap operator will return the next.handle(request)
        return this.inj.get(CnafUserService).getTokenJWTObservable().switchMap((token) => {
            // we use the output from your tokenRequest to clone the current request
            const newRequest = request.clone({ headers: request.headers.set('Authorization', `${token}`) });
            return next.handle(newRequest);
        })
    }
    return next.handle(request);
}

据我所知,没有必要订阅你的getTokenJWTObservable,因为它被认为是switchMap操作的源可观察对象。 In an angular blog post它被描述为这样。

  

如果我们订阅了可观察的结果,那将触发一个   订阅源Observable

我猜你的截取流程中的somwhere,会对你的返回observable进行订阅,因此会触发对令牌的get请求。