【问题标题】:issue mixing promises with HttpInterceptor observables?将 Promise 与 HttpInterceptor observables 混合问题?
【发布时间】:2018-02-09 12:06:59
【问题描述】:

我正在使用 HttpInterceptor 重新发送带有令牌的请求,以防它们返回 401。 这在我刚刚获取缓存令牌之前效果很好。由于 Firebase 令牌似乎没有自动刷新(尽管使用 forceRefresh),我现在正尝试在拦截器类中实时获取新令牌。问题是现在请求没有被重新发送。

这是我的完整拦截器:

export class CustomHttpInterceptor implements HttpInterceptor {
    constructor(private injector: Injector) {
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        const formRequest = req.clone({ headers: req.headers.set('Content-Type', 'application/x-www-form-urlencoded') });

        return next.handle(formRequest).map((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                console.log("GOT RESPONSE WITHOUT ERROR. JUST PASSING THROUGH.");
                return event;
            }
        }).catch(err => {
            console.log("==INTERCEPTOR== CATCH ERROR RESPONSE");
            if (err instanceof HttpErrorResponse) {
                console.log("==INTERCEPTOR== IS HTTP ERROR RESPONSE");
                if (err.status === 401) {
                    console.log("==INTERCEPTOR== IS 401");
                    let postParams = new HttpParams({ fromString: req.body });
                    if (postParams.has('t')) {
                        //401 while we already provided a token, so a real login is required
                        console.log("==INTERCEPTOR== PROVIDED TOKEN, STILL PROBLEM");
                        throw new Error("NOT_AUTH");
                    } else {
                        // most likely session expired, resend token
                        console.log("==INTERCEPTOR== REQUEST WAS WITHOUT TOKEN, RESEND WITH TOKEN");
                        // get AuthProvider here
                        const auth = this.injector.get(AuthProvider);
                        // token will come in a promise
                        return auth.getToken().then(idToken => {
                            console.log("GOT NEW TOKEN, resending request with token " + idToken);
                            //add token to post params
                            let newPostParams = postParams.append('t', idToken); ====> SUCCESFULLY GOT NEW TOKEN
                            //clone request and add new body
                            const changedReq = formRequest.clone({
                                method: 'POST',
                                body: newPostParams.toString()
                            });
                            return next.handle(changedReq);   ====> THIS IS NOT PERFORMED
                        },
                        error => {
                            throw(error);
                        });
                    }
                }
            } else {
                throw(err);
            }
        })
    }
}

如果没有这个 Promise 函数来获取新的令牌,请求将使用最后的“next.handle(changedReq);”重新发送。我没有发现我在这里做错了什么。这是因为我将 promise 与 observables 混合在一起造成的吗?

【问题讨论】:

  • 什么是formRequest 我猜是undefined
  • 嗨@RahulSingh,感谢您的回复。我在这里复制时不小心剥离了一行,它定义了formRequest。它是请求的克隆(因为我在那里添加了一个标头)。我更新了上面的代码块。
  • 你为什么用return auth.getToken().then(idToken =&gt; {试试去掉return
  • @RahulSingh,我需要这样做,因为 catch 期望通过返回一个新的 observable 或抛出一个错误来处理。因此,删除此返回会导致 TS 错误。
  • 使用 toPromise 更好地将 promise 转换为 observable

标签: angular observable angular-promise angular-http-interceptors angular-observable


【解决方案1】:

按照 Rahul Singh 的建议,通过将 promise 转换为 observable 并使用 flatMap 来获得嵌套的 observable 返回来解决:

let promise = auth.getToken();
let observable = Observable.fromPromise(promise);
return observable.first().flatMap(idToken => {
    console.log("GOT NEW TOKEN, resending request with token " + idToken);

    //add token to post params
    let newPostParams = postParams.append('t', idToken);
    //clone request and add new body
    const changedReq = formRequest.clone({
        method: 'POST',
        body: newPostParams.toString()
    });
    return next.handle(changedReq);
});

【讨论】:

    猜你喜欢
    • 2019-09-26
    • 2018-12-25
    • 2016-07-15
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多