我正在Angular 8
中构建应用程序的前端。此应用程序使用OAuth 2
实现来管理身份验证(密码授予),因此任何HTTP
请求(令牌端点的请求除外)都需要在其标头上具有有效的access_token。
要提供上述令牌,我做了一个Angular interceptor
,可以从另一个服务中检索令牌,然后将其附加到截获的HTTP
请求中。令牌检索方法不会直接提供令牌,而是会提供可观察的结果,最终将其解析为有效的令牌,因此我做出了此选择,因为访问令牌可能无法立即使用,如果令牌已过期,则应用程序需要使用{ {1}}调用,然后刷新的令牌可以传递到HTTP
拦截器。
我遇到的问题是,尽管我做了很多尝试,但拦截器并没有等待令牌的检索,因此最终拦截器被跳过,并且HTTP
请求没有附加任何令牌。 / p>
这是我的拦截器的代码,HTTP
是retrieveValidToken
,它返回令牌。
Observable
答案 0 :(得分:2)
可观察对象是异步的。订阅方法之外的代码将不等待其中的代码。
您应返回可观察的结果,而不仅仅是返回其订阅范围内的结果:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.includes('localhost:3000') && !req.url.endsWith('token')) {
return this.facadeService.retrieveValidToken()
.subscribe(
res => {
const clone = req.clone({ setHeaders: { Authorization: `Bearer ${res}` } });
return next.handle(clone);
}
);
} else {
return next.handle(req);
}
}
类似的东西:
答案 1 :(得分:0)
问题在于,“拦截”方法应立即返回可观察到的状态,因此,不要订阅“ this.facadeService.retrieveValidToken()”,请使用以下代码:
return this.facadeService.retrieveValidToken().pipe(
mergeMap(token =>
next.handle(req.clone({ setHeaders: { Authorization: 'Bearer ${token}' }))
)
)