当前位置: 首页 > 知识库问答 >
问题:

在 Angular http 拦截器中刷新令牌后重试请求

姜良哲
2023-03-14

我有 401 拦截器,当access_token过期时,有一个请求的成功案例。拦截器重新加载令牌并返回 next.handle(customReq)。但是当同时发出 2 个或更多请求并且两个请求的令牌都已过期时,我遇到了问题,因为第二个请求尝试再次刷新,但现在刷新令牌无效。所以。。。。我尝试设置一个标志只执行一次,并使用自定义可观察量返回。问题是组件现在永远不会成功,我无法删除加载器。

HTTP 拦截器:

    return next
        .handle(customReq).pipe(
        tap((ev: HttpEvent < any > ) => {
            if (ev instanceof HttpResponse) {
                this.setApiStatus(ApiStatusCode.ACTIVE);
                this.interceptorIgnore.removeIgnore(request.url);
            }
        }),
        catchError(resp => {
            if (resp instanceof HttpErrorResponse) {
                switch (true) {
                    // Unauthorized
                    case resp.status === 401:
                        return this.attemptToRefreshToken(apiRequest, customReq, next);
                    // More code unnecessary ....
                }
            }

            return throwError(resp);
        })
    );

尝试ToRefreshToken方法:

attemptToRefreshToken(apiRequest: ApiRequest, customReq: HttpRequest<any>, next: HttpHandler) {


        const retryRequest = () => {
            this.updatingToken = false;
            customReq = customReq.clone({
                headers: apiRequest.buildHeader()
            });
            return next.handle(customReq);
        };

        if (!this.updatingToken) {
            this.updatingToken = true;
            const tokenRequestData = this.apiAuth.refreshTokenData();
            return this.http.request(tokenRequestData.opts.method, tokenRequestData.url, tokenRequestData.opts)
            .pipe(flatMap((token: ResponseTokenFormat) => {
                ApiAuth.storedToken = token;
                this.usersService.queryUsersUsename(ApiAuth.storedUser).then(([user]) => {
                    if (user && !user.isAdmin) {
                        this.sessionService.setUserPermissions(user);
                    }
                });
                this.tokenUpdated.next();
                return retryRequest();
            }));
        }

        return this.tokenUpdated$.pipe(
            flatMap(() => retryRequest())
        );       

}

当下一个()被调用并正常工作时,重试请求会执行,但它永远不会通知服务女巫调用这个超文本传输协议请求。当我刷新令牌时,返回重试请求();服务可以订阅。

我做错了什么?也许是Observable?

共有1个答案

陈晟睿
2023-03-14

我认为你可能不得不使用exhaustMap而不是flatMap,试图刷新令牌。

它们是如何工作的?

  • 平面图:立即为任何源项目创建一个可观察对象,所有以前的可观察对象都保持活动
  • 耗尽地图:源项被忽略,而上一个可观察项未完成。
 类似资料:
  • 问题内容: 我有一个有角度的应用程序,有时每个状态会执行多个$ http.get请求。该应用将JWT用于带有刷新令牌的用户身份验证。API服务器会发送由于身份验证错误而失败的每个请求。我做了一个请求,该请求在401错误时请求带有刷新令牌的新令牌,然后重新发送原始请求。 问题是,如果一个状态发出例如2个$ http.get请求,并且都获得401响应,那么我将访问令牌更新两次。显然,我只想刷新一次令牌

  • 我需要(在拦截器类中)对403禁止的HTTP状态(获取/刷新)JWT令牌作出反应,并使用新令牌重试请求。 在下面的代码中,当服务器返回错误响应时,它将转到成功回调(而不是像我预期的那样进入错误回调),事件是typeof object(这在错误响应的反应中是无用的)。事件对象如下所示:{type:0}。 问题: -当我需要刷新accessToken并重试http请求时,如何在HttpIntercep

  • 您好,我正试图通过刷新令牌并重试请求,找出如何实现新的角度拦截器和处理错误。这是我一直遵循的指南:https://ryanchenkie.com/angular-authentication-using-the-http-client-and-http-interceptors 我成功缓存失败的请求,并可以刷新令牌,但我不知道如何重新发送以前失败的请求。我还想让它与我目前使用的解析器一起工作。 t

  • 我有一个使用express api的react应用程序。我正在尝试在访问令牌过期时刷新令牌。我正在使用axios拦截器来实现这一成就。 它卡在某个地方了。我使用console.log来调试它。从控制台; 发布http://localhost:5000/api/auth/token?null 401(未经授权) 之后什么都没发生。我该怎么办?谢谢你的帮助

  • 我正在尝试从应用程序服务中获取Google的刷新令牌,但我不能。 日志说 2016-11-04T00:04:25 PID[500]收到的详细请求:获取https://noteappsvr.azurewebsites.net/.auth/login/google?access _ type = offline 2016-11-04t 00:04:25 PID[500]从https://account

  • 我正在从事一个spring boot angular项目,其中用户从angular前端登录到spring boot上的身份验证api,该api返回一个JWT令牌。我还在Angular上设置了一个拦截器,该拦截器为所有请求附加带有JWT令牌的授权头。 我正在寻找一种拦截angualar请求的方法,这样当spring boot在JWT令牌过期后抛出401错误时,Angular前端将尝试使用过期的JWT