首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >angular-7-interceptor-retry-requests-after-token-refresh

angular-7-interceptor-retry-requests-after-token-refresh
EN

Stack Overflow用户
提问于 2019-12-31 10:38:13
回答 2查看 2.5K关注 0票数 1

我试图在令牌过期的情况下为失败的请求实现一个拦截器。我尝试过多种方法,但仍然没有成功。

我已经参考了下面的URL &阅读多个博客。每个人都在建议转换地图方法,但不是和我一起工作。角4截止器在令牌刷新后重试请求

我尝试将所有请求收集到cachedRequests: Array> =[]中;但是不知道如何使用它来重新触发失败的请求。

在成功的刷新令牌之后,this.next.handle(请求)不会被召回。不过,我可以看到更新的请求对象。

有人能指出角7中的参考点吗?

"rxjs":"~6.3.3",“rxjs”:"^6.5.2",以实现拦截器。

下面是为我工作的代码,但只得到令牌的响应。

代码语言:javascript
复制
代码语言:javascript
复制
handleError(request: HttpRequest<any>, next: HttpHandler, err) {
代码语言:javascript
复制
        if (err instanceof HttpErrorResponse) {
代码语言:javascript
复制
            if (err.status === 401) {
代码语言:javascript
复制
                this.service.getNewToken().pipe(filter(token => token != null),
代码语言:javascript
复制
                    take(1),
代码语言:javascript
复制
                    switchMap((token: any) => {
代码语言:javascript
复制
                        console.log('token', token);
代码语言:javascript
复制
                        if (token && token.access_token && token.refresh_token) {
代码语言:javascript
复制
                            sessionStorage.setItem('accessToken', token.access_token);
代码语言:javascript
复制
                            sessionStorage.setItem('refreshToken', token.refresh_token);
代码语言:javascript
复制
                        }
代码语言:javascript
复制
                        request = this.addHeader(request);
代码语言:javascript
复制
                        request.headers.getAll('Authorization');
代码语言:javascript
复制
                        return next.handle(request);
代码语言:javascript
复制
                    })).subscribe(results => this.subject.next(results));
代码语言:javascript
复制
            }
代码语言:javascript
复制
        }
代码语言:javascript
复制
    }
代码语言:javascript
复制
```

更新2:在尝试了多种方法之后,我找到了

  1. 返回next.handle(请求);<--这根本不需要调用
  2. 返回next.handle(请求).subscribe();<--这将被调用,但不会更新对请求组件的响应。

指针欣赏

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-31 10:36:34

回复晚了。我就是这么做的。

工作与并行请求以及。

代码语言:javascript
复制
import { HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse, HttpEvent, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
import { GlobalService } from './global.service';
import { tap, mergeMap, switchMap, filter, take, flatMap, catchError } from 'rxjs/operators';
import { Observable, Subject, throwError, of, BehaviorSubject } from 'rxjs';


@Injectable()
export class InterceptorService implements HttpInterceptor {
    private isRefreshing = false;
    private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
    constructor(public globalService: GlobalService) {
    }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        request = this.addHeader(request);
        // console.log('request ', request);
        return next.handle(request).pipe(catchError((error: any) => {
            if (error instanceof HttpErrorResponse) {
                if (error.status === 401) {
                    if (!this.isRefreshing) {
                        this.isRefreshing = true;
                        this.refreshTokenSubject.next(null);
                        request = this.addHeader(request);
                        console.log('Token request');
                        return this.globalService.getRefershToken().pipe(
                            switchMap((token: any) => {
                                console.log('inside token');
                                this.isRefreshing = false;

                                if (token && token.access_token && token.refresh_token) {
                                    sessionStorage.setItem('accessToken', token.access_token);
                                    sessionStorage.setItem('refreshToken', token.refresh_token);
                                }
                                // request = this.addHeader(request);
                                // console.log('request: ', request);
                                this.refreshTokenSubject.next(token);
                                return next.handle(this.addHeader(request));
                            }));

                    } else {
                        console.log('inside else call');
                        console.log('token : ', this.refreshTokenSubject.getValue());
                        return this.refreshTokenSubject.pipe(
                            filter(token => (token != null && token != undefined)),
                            take(1),
                            switchMap(() => {
                                console.log('adding header in else');
                                return next.handle(this.addHeader(request))

                            }));
                    }
                }
            }
        }));
    }

    private addHeader(request: HttpRequest<any>) {
        let getEndPoint = request.url.split('/')[request.url.split('/').length - 1];
        if (getEndPoint !== 'refreshToken') {
            const accessToken = sessionStorage.getItem('accessToken');
            request = request.clone({
                setHeaders: {
                    Authorization: `Bearer ${accessToken}`
                }
            });
        } else if (getEndPoint === 'refreshToken') {
            const refreshToken = sessionStorage.getItem('refreshToken');
            request = request.clone({
                setHeaders: {
                    applicationCode: environment.applicationCode,
                    'refresh-token': `${refreshToken}`,
                }
            });
        }
        return request;
    }
}
票数 5
EN

Stack Overflow用户

发布于 2022-08-22 15:13:51

在HTTP错误401导致api失败后,令牌刷新api被调用,所有失败和缓存的请求都可以使用http拦截器重新尝试。

代码语言:javascript
复制
if (this.isRefreshingToken && !req.url.endsWith(tokenURL)) {
      // check if unique url to be added in cachedRequest

      if (urlPresentIndex == -1) {
        this.cachedRequests.push(req);
        return this.tokenSubject.pipe(
          switchMap(() => next.handle(req)),
          tap((v) => {
            // delete request from catchedRequest if api gets called

            this.cachedRequests.splice(
              this.cachedRequests.findIndex(
                (httpRequest) => httpRequest.url == req.url
              ),
              1
            );
            return EMPTY;
          })
        );
      } else {
        //already in cached request array

        return EMPTY;
      }
    }

有关更多细节,请阅读我的媒体文章Token-Refresh-Interceptor-retry-failed-Requests

看看它是如何工作的,stackblitz

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59542951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档