[英]How to retrieve data from an Observable and use it in an Interceptor?
我正在Angular 8
中构建应用程序的前端。 此应用程序使用OAuth 2
实现来管理身份验证(密码授予),因此任何HTTP
请求(令牌端点除外)都需要在其 Z099FB995346F31C749F6E40DB0F395E3 上具有有效的访问令牌
为了提供所述令牌,我制作了一个Angular interceptor
,该拦截器从另一个服务中检索令牌,然后将其附加到拦截的HTTP
请求中。 令牌检索方法不直接给出令牌,而是最终解析为有效令牌的可观察对象,我做出此选择是因为访问令牌可能不会立即可用,如果令牌过期,应用程序需要使用HTTP
刷新它调用然后刷新的令牌可以传递给HTTP
拦截器。
我遇到的问题是,尽管我进行了多次尝试,但拦截器并没有等待检索令牌,因此最后会跳过拦截器,并且在没有附加任何令牌的情况下发出HTTP
请求。
这是我的拦截器的代码, retrieveValidToken
是返回令牌的Observable
。
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { FacadeService } from './facade.service';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor {
constructor(private facadeService: FacadeService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.includes('localhost:3000') && !req.url.endsWith('token')) {
this.facadeService.retrieveValidToken()
.subscribe(
(res) => {
const clone = req.clone({ setHeaders: { Authorization: `Bearer ${res}` } });
return next.handle(clone);
},
(err) => {
const clone = req.clone({ setHeaders: { Authorization: `Bearer ` } });
return next.handle(clone);
}
);
} else {
return next.handle(req);
}
}
}
Observables 是异步的。 subscribe 方法外面的代码不会等待里面的代码。
您应该自行返回 observable,而不仅仅是在其订阅中返回结果:
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);
}
}
相似的东西:
问题是 'intercept' 方法应该立即返回 observable,所以不要订阅 'this.facadeService.retrieveValidToken()' 使用以下代码:
return this.facadeService.retrieveValidToken().pipe( mergeMap(token => next.handle(req.clone({ setHeaders: { Authorization: 'Bearer ${token}' })) ) )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.