網站搜尋

typescript - Angular HttpInterceptor 處理從伺服器返回的 200 回應中的令牌刷新


我正在尋找一種方法,在收到 200 HttpResponse 訊息中刷新 token 後重新調用當前請求。我已經有一個錯誤捕獲來處理 401,但有些情況下使用者會被視為「未認證」,而該狀態會在 200 回應中返回。當然,這種情況永遠不會觸發錯誤捕獲。我有以下程式碼,它會獲取新的 access_token 並使用 token 標頭建立新的「複製」請求,但在調用時

next.handle(newReq)

它沒有任何作用。如果我刷新頁面,它會發出請求並且一切正常,但我希望它能使用 HttpResponse 中的 NEW 令牌完成請求。有人可以指引我正確的方向嗎?

addToken(req: HttpRequest<any>, token: string): HttpRequest<any> {
    return req.clone({ setHeaders: { Authorization: 'Bearer ' + token }})
}

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
    return next.handle(this.addToken(req, window.sessionStorage.getItem('access_token'))).pipe(map((event:any) => {
        if (event instanceof HttpResponse) {
            console.log('event--->>>', event);
            if(event.body && event.body.StatusCode == "Unauthenticated"){
            this.accSvc.RefreshAccessToken().subscribe((response:any) => {
                console.log(response);
                    console.log("Old Token: " + this.oldToken);
                    this.usrSvc.SetSessionTokensAndTime(response.access_token, response.refresh_token, response.expires_in);
                    var tok = window.sessionStorage.getItem("access_token");
                    console.log("New Token: " + tok);
                    var newReq = this.addToken(req, tok);
                    return next.handle(newReq); //THIS SHOWS THE 'newReq' has the NEW TOKEN, but when stepping over this in debug, it does nothing until page refreshed.

            })
            }
        }
        return event;
    })).pipe(
        catchError((error: HttpErrorResponse):any => {
            if(error instanceof HttpErrorResponse){
                switch ((<HttpErrorResponse>error).status) {
                    case 401:
                        return this.handle401Error(req, next);
                }
            } else {
                return throwError(error);
            }

          })
    )
}

答案#1

對於那些正在嘗試這樣做的人,根據我所研究和嘗試的結果,為了讓攔截器在遇到“未授權”時使用 next.handle(req) 處理請求,它必須處理 401。 我們不得不更改我們的 API,以返回 401 而不是帶有未授權狀態碼的 200。 到那時,攔截器在 401(未授權)的情況下就按設計工作了。

我的想法是,你無法在一個 HttpResponse 事件中完成中介軟體的最終處理、執行最終調用並將後續調用排入隊列。

如果你能控制你的 API,請更新以返回 401。