请求新的访问令牌并继续上一个请求

时间:2020-02-17 10:56:16

标签: angular typescript angular-http-interceptors

我正在使用Angular / Typescript。该应用程序与API通信,access_token存储在存储器中。

在每个请求上,拦截器都会检查access_token是否仍然有效。

当access_token过期时,应用程序需要使用access_token刷新refresh_token并继续上一个请求(使用新的access_token

问题 我无法克隆原始请求(带有过期的令牌)并执行它。 请求新access_token的调用正在干扰拦截器。 最好的方法是:

  1. 请求新令牌。
  2. 设置新令牌。
  3. 恢复具有已过期令牌的呼叫并克隆成功运行吗?

拦截器:

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // add authorization header with jwt token if available
        if (!this.isRefreshing) {
            if (this.authenticationService.checkLoginState()) {
                // Check if access_token is valid.
                this.currentUser = JSON.parse(localStorage.getItem('auth'));
                if (new Date(this.currentUser.access_token_expires) > new Date()) {
                    // Access token is valid, clone request and continue.
                    request = request.clone({
                        setHeaders: {
                            Authorization: `Bearer ${this.currentUser.access_token}`
                        }
                    });
                    return next.handle(request);
                } else {
                    // Token is not valid, request new token with reLogin().
                    this.reLogin().then(any => {
                        // New token has been set, now run old request with new token.
                        return next.handle(request);
                    }, error => {
                        this.authenticationService.logout();
                    });
                }
            }
        } else {
            return next.handle(request);
        }
    }

重新登录:

    reLogin() {
        return new Promise(function (resolve, reject) {
            this.isRefreshing = true;
            // Check if refresh token is valid
            if (new Date(this.currentUser.refresh_token_expires) > new Date()) {
                this.authenticationService.loginWithRefreshToken(this.currentUser.refresh_token).subscribe(data => {
                    // Using refresh_token was successful
                    this.currentUser = JSON.parse(localStorage.getItem('auth'));
                    this.isRefreshing = false;
                    resolve();
                }, error => {
                    console.error(error);
                    reject();
                });

        });
    }

1 个答案:

答案 0 :(得分:0)

第一句话是在克隆请求时为该请求创建一个新的const,而不是将其分配给旧的const。 我认为问题是当您调用reLogin并期望在then中可以访问带有更新令牌的新请求时。但是您仍然处于旧的request的上下文中。因此,您可能应该从access_token返回reLogin,然后再将其设置在请求的克隆上。