1

I have a problem, i want to add Token in my API HTTP request. For get my token, i make http request. Here my code :

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);
}

}

The service :

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

How, i call for get the token and then return the request with header ?

Thank for your help

Samshay
  • 123
  • 1
  • 2
  • 10

1 Answers1

1

I haven't tried this solution, so feel free to correct me if I'm wrong here.

The problem seems to be that inside your getRequestWithAuthorization function you are not return anything, although you're trying to get something from there.

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
}

You are just returning the request from the subscribe function, but as an inner function (at least that's my understanding of it) the request is not passed any further. Currently you are not doing anything with the request.

This question here is about a similar problem that you have. What we ultimately want to return is next.handle(request) which is an observable. Before we can do that, we have to perform a request for your token which is also an observable. To return the correct observable in the end we use the switchMap operator. We will get the token, use the observable result to alter the request and return the next.handle(request). I think it should look like this.

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);
}

As far as I know there is no need to subscribe to your getTokenJWTObservable because it is considered the source observable of the switchMap operation. In an angular blog post it is described like this.

if we subscribe to the result observable, that will trigger a subscription to the source Observable

I guess that somwhere in your intercept flow, a subscription will be made to your returning observable and will therefore trigger the get request for the token aswell.

Benedikt Schmidt
  • 2,178
  • 16
  • 20