I am attempting to implement OIDC in an Angular project. Eveything was going great until I tried to implement an HPPT interceptor to set the Authorization header. I have a method on the auth service that returns the token as a promise: `
getAccessToken()
{
return this._userManager.getUser().then(user =>
{
if(!!user && !user.expired)
{
return user.access_token
}
else
{
return null
}
})
}
Here is my intercept method
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
{
if(req.url.startsWith(Constants.avlApiRootUrl))
{
return from(this._authService.getAccessToken().then(token =>{
const headers = new HttpHeaders().set('Authorization', `Bearer ${ token }`)
const authReq = req.clone({headers})
return next.handle(authReq)
}))
}
else
{
return next.handle(req)
}
}
` When I try to call this from the intercept class on the HTTPInterceptor I get an error: Type 'Promise<Observable>' is missing the following properties from type 'Observable': source, operator, lift, subscribe, and 3 more.ts(2740)
I understand that I am returning the wrong type but everything I can find about this says to use a toPromise method that has been depreciated. Can anyone tell me how to do this, I'm out of ideas. More than having someone write my code for me (which I would take at this point) I'd really like to understand this so if you can point to a write up or documentation That would be awesome.
CodePudding user response:
Since you're returning next.hande()
within your promise, it's returning Observable<Promise<Observable<T>>>
.
You need to return plain Observable<T>
:
To accomplish this you can make modifications to your observable stream using .pipe()
with some operators. We can start with your promise wrapped in from()
, like you had, then map
the result into a new headers object, then into an auth reqeust object, then finally into a call to next.handle()
:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if(req.url.startsWith(Constants.avlApiRootUrl)) {
return from(this._authService.getAccessToken()).pipe(
map(token => new HttpHeaders().set('Authorization', `Bearer ${ token }`)),
map(headers => req.clone({headers})),
mergeMap(authReq => next.handle(authReq))
);
}
return next.handle(req)
}
The reason for the mergeMap
at the end is because we want to emit the emissions from next.handle()
, not the next.handle()
observable itself.