简体   繁体   English

Angular HttpInterceptor 处理令牌刷新 200 以内来自服务器的响应

[英]Angular HttpInterceptor Handle Token Refresh Within 200 Response From Server

I am looking for a way to re-call the current request after refreshing a token within a 200 HttpReponse message.我正在寻找一种在 200 HttpReponse 消息中刷新令牌后重新调用当前请求的方法。 I have an error catch to handle a 401, but there are cases when a user will be "Unauthenticated" and that status will be returned in a 200 Response.我有一个错误捕获来处理 401,但在某些情况下,用户将“未经身份验证”并且该状态将在 200 响应中返回。 This of course never falls into the Error Catch.这当然永远不会落入错误捕获。 I have the code below which fetches the new access_token and builds new "cloned" request with the token header, but then when calling我有下面的代码,它获取新的 access_token 并使用令牌 header 构建新的“克隆”请求,但是在调用时

next.handle(newReq) next.handle(newReq)

it does nothing.它什么也不做。 If I refresh the page it makes the request and all works, but I want it to complete the request with the NEW token from within the HttpResponse.如果我刷新页面,它会发出请求并且一切正常,但我希望它使用 HttpResponse 中的 NEW 令牌完成请求。 Can someone point me in the right direction?有人可以指出我正确的方向吗?

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

          })
    )
}

For those who are trying to do this, from what I have researched and tried, in order for the interceptor to handle the request using next.handle(req) in the case of "Unauthorized" it must be dealing with a 401. We had to change our api to return the 401 vs 200 with Unauthorized StatusCode.对于那些试图这样做的人,根据我的研究和尝试,为了让拦截器在“未经授权”的情况下使用 next.handle(req) 处理请求,它必须处理 401。我们有更改我们的 api 以返回 401 与 200 与未经授权的状态代码。 At that point, the interceptor worked as designed in the case of 401(Unauthorized).此时,拦截器在 401(未经授权)的情况下按设计工作。

My thought is that you cannot finalize the middleware, executing the final call and queue subsequent calls from within an HttpReponse event.我的想法是您无法完成中间件,执行最终调用并将后续调用从 HttpReponse 事件中排队。

If you have control over your API, Update to return the 401.如果您可以控制 API,请更新以返回 401。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM