angular - 在服务器响应 401 错误后使用拦截器附加正确的令牌
问题描述
我正在尝试为所有身份验证问题创建一个错误处理方法。我遇到了一个问题,正在调用我的 authTokenService.getAmadeusAuthToken$ 方法,但由于它是返回新令牌的后调用,因此需要更长的时间来解决,同时 catchError obvservable 在令牌之前返回 next.handle取回。我尝试了几种不同的方法,但我不知道让拦截器方法等到 authTokenService.getAmadeusAuthToken$ 完成的最佳方法。这是我的代码:
My Interceptor:
intercept(req: HttpRequest<any>, next: HttpHandler) {
return next.handle(req).pipe(
catchError((response: HttpErrorResponse) => {
return next.handle(req).pipe(
tap(test => {
this.authTokenService.getAmadeusAuthToken$().pipe(
).subscribe(token => {
const authReq = req.clone({
headers: req.headers.append('Authorization', 'Bearer ' + token.access_token)
});
return next.handle(authReq);
})
})
)
})
发布调用以获取新令牌的方法
getAmadeusAuthToken$(): Observable<any>{
const httpOptions = { headers: new HttpHeaders().set('Content-Type', "application/x-www-form-urlencoded")}
return this.http.post<Token>('https://test.api.amadeus.com/v1/security/oauth2/token', this.body, httpOptions)
}
为了确保拦截方法正常工作,我进行了一个 API 调用来获取新令牌并将其硬编码。拦截方法的工作方式非常棒,因为没有竞争条件,并且拦截器返回 next.handle()立即获得令牌。
intercept(req: HttpRequest<any>, next: HttpHandler) {
return next.handle(req).pipe(
catchError((response: HttpErrorResponse) => {
const authReq = req.clone({
headers: req.headers.append('Authorization', 'Bearer ' + "lkVkfilWizfcuyVpXBQsA08XkUy5")
});
return next.handle(authReq);
})
所以基本上我想确保拦截器等待 authTokenService.getAmadeusAuthToken$ 完成获取令牌,然后才返回带有令牌的新 next.handle,我在这里缺少什么?
解决方案
Instead of returning next.handle(...)
, you actually want to return an observable that first calls to get a new token, then executes the next request.
To avoid subscribing we can use switchMap
to handle the subscribing for us:
intercept(req: HttpRequest<any>, next: HttpHandler) {
return this.authTokenService.getAmadeusAuthToken$().pipe(
switchMap(token => {
const headers = req.headers.set('Authorization', `Bearer ${token.access_token}`);
const authReq = req.clone({ headers });
return next.handle(authReq);
})
);
}
推荐阅读
- excel - Excel 公式显示为“=#NULL”返回正确结果
- javascript - GraphQL:返回新的 Promise((resolve,object)
- ios - 如何在 Crashlytics 中使用 CLSStackFrame?
- webpage - 网页启动错误
- python - Google App Engine dev_appserver.py:watcher_ignore_re 标志“不是 JSON 可序列化的”
- r - R中的菊花功能警告
- java - Apache Maven:-source 1.5 中不支持 Diamond 运算符
- python-2.7 - Pycharm 后台任务永远占用
- c# - 如何像 C++ 一样在 C# 中初始化
- symfony - Doctrine ORM:使用更新级联选项手动添加 fk 来验证模式