与HttpInterceptor observables混合承诺? [英] issue mixing promises with HttpInterceptor observables?

查看:68
本文介绍了与HttpInterceptor observables混合承诺?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用HttpInterceptor重新发送带有令牌的请求,以防它们返回401. 在我刚刚获取缓存的令牌之前,这种方法已经很好地工作了.由于Firebase令牌似乎并没有自动刷新(尽管使用forceRefresh),所以我现在试图在拦截器类中实时获取一个新的令牌.问题是现在请求没有被重新发送.

I am using the HttpInterceptor to resend requests with a token in case they return a 401. This had worked well before, when I was just taking the cached token. Since the Firebase token does not seem to be automatically refreshed (using forceRefresh though), I am now trying to get a fresh token in realtime in the interceptor class. The problem is that now the request is not being re-send.

这是我的全部拦截器:

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);"重新发送.我在这里没有发现我做错了什么.这是因为我将诺言与可观察物混在一起了吗?

Without this promise function to get a new token, the request is being resend using the last "next.handle(changedReq);". I am not finding what I am doing wrong here. Is this caused because I am mixing promises with observables?

推荐答案

通过将承诺转换为Rahul Singh建议的可观察值并使用flatMap来获得嵌套的可观察返回值来解决:

Solved by converting the promise to an observable as suggested by Rahul Singh, and using flatMap in order for the nested observable return:

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);
});

这篇关于与HttpInterceptor observables混合承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆