【问题标题】:Refresh token inteceptor using NGRX使用 NGRX 刷新令牌拦截器
【发布时间】:2020-02-10 10:14:16
【问题描述】:

所以我创建了一个刷新令牌 http 拦截器,它从 API 中查找 401 错误,然后尝试刷新用户令牌。

那里有很多教程,这里有很多关于如何处理令牌刷新的教程,但是,如果不是全部的话,很多教程只是使用 inteceptor 中的服务,而我想使用 NGRX 调度操作。

我的操作(见下文)很简单,REFRESH_TOKEN 触发了一个调用 API 端点的效果,该端点有望为用户返回一个新的令牌(我还有其他效果来处理该操作的成功/失败、重定向或相应地保存数据)。

我对 inteceptor 的第一次尝试:

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        this.loaded$ = this.auth.pipe(select(selectAuthLoaded));
        this.loading$ = this.auth.pipe(select(selectAuthLoading));

        // @ts-ignore
        return next.handle(request).pipe(catchError(error => {
            if (error instanceof HttpErrorResponse && error.status === 401) {
                return this.handle401Error(request, next);
            } else {
                return throwError(error);
            }
        }));
    }

    private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
        this.loading$.subscribe(isLoading => {
            this.storage.getItem('refresh_token').subscribe(refreshToken => {
                if (!isLoading && refreshToken) {
                    this.auth.dispatch(new RefreshToken(refreshToken));
                } else {
                    return next.handle(request);
                }
            });
        });
    }

}

我在这里的想法是,如果是 401,请运行 handle401ERror 函数。这首先检查是否加载了身份验证状态,并从本地存储中获取用户刷新令牌(这很糟糕,一旦我确定了它就会更改为 COOKIE),如果加载了身份验证并且有一个刷新令牌然后调度REFRESH_TOKEN 操作。

这似乎导致以下错误:

You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

【问题讨论】:

  • 很少有直接的想法...handle401error 不会返回任何内容,您在可以管道时订阅。试试this
  • 嗨,感谢您的评论,正如我在帖子中所避免的那样,那里有很多教程(这是我也找到的),但他们似乎都只是使用该服务直接,而我想调度一个动作(你不能管道)。

标签: angular ngrx angular-http-interceptors


【解决方案1】:

我也遇到过这个问题。在我找到更好的解决方案之前,我只是利用了效果本身。我不确定这是否有资格作为答案,但这是我迄今为止使用的代码:

if (error.msg === 'invalid_token') {
  this.authService.dispatch(fromAuthStore.refreshToken());
  return this.authEffects.refreshTokenSuccess$.pipe(
    take(1),
    mergeMap(() => {
      return next.handle(this.setRequest(req));
    })
  );
} else {
  return throwError(error);
}

希望对你有帮助

编辑:这是一个链接,可能会提供更多解释并提供替代方案。基本上,你最终会听 ngrx。 https://netbasal.com/listening-for-actions-in-ngrx-store-a699206d2210

【讨论】:

  • 谢谢,这不是最优雅的解决方案,但是,您提供的链接是黄金,我可能会尝试订阅调度程序,如果没有,那么您的解决方案可能是一个很好的解决方案,直到找到一个更好的解决方案。我会尽量让你知道我是怎么过的。再次感谢
猜你喜欢
  • 2020-05-12
  • 2019-07-09
  • 1970-01-01
  • 2022-11-03
  • 2017-02-25
  • 1970-01-01
  • 2021-05-17
  • 2017-12-31
  • 2023-03-23
相关资源
最近更新 更多