令牌过期时获取刷新令牌

时间:2021-04-15 12:11:45

标签: angular interceptor refresh-token

每次出现 401 以外的错误时,我都必须重试 5 次并获取刷新令牌。我正在使用下面的代码,它以无限循环结束

服务实现:

@Injectable()
export class ApiService {
        public authenticate(
        credentials: Credentials,
        accessCode: string): Observable<Auth> {
        const requestBody: Record<string, any> = { credentials, access_code: accessCode};
        return this.http.post<Auth>(this.credentialsAuthUrl, requestBody).pipe(
          map((res: Auth) => {
            const auth = new Auth(res);
    
            if (!this.validateJwtToken(accessCode, auth)) {
              throw Error('invalid_token');
            }
            sessionStorage.setItem('accessToken', auth.accessToken);
            sessionStorage.setItem('refreshToken', auth.refreshToken);
            localStorage.setItem('some-accessToken', auth.accessToken);
            return auth;
          })
        );
      }
}

拦截器:

Injectable()
export class CustomInterceptor implements HttpInterceptor {
      
      public constructor(private apiService: ApiService) {}
     
      public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
       return next.handle(request).pipe(
          retryWhen((error) =>
            error.pipe(
              retryWhen(this.genericRetryStrategy()),
              catchError((err) => of(err))
            )
          )
        );
      }
}

重试逻辑:

private genericRetryStrategy = ({
        maxRetryAttempts = 5,
        scalingDuration = 1000,
        excludedStatusCodes = [ 401 ]
      }: {
        maxRetryAttempts?: number;
        scalingDuration?: number;
        excludedStatusCodes?: number[];
      } = { }) => (attempts: Observable<any>) => {
        return attempts.pipe(
          mergeMap((error, i) => {
            const retryAttempt = i + 1;
    
            if (
              retryAttempt > maxRetryAttempts ||
              excludedStatusCodes.find((e) => e === error.status)
            ) {
              return throwError(error);
            }
            console.log(
              `Attempt ${retryAttempt}: retrying in ${retryAttempt }ms`
            );
    
            return forkJoin(
              this.apiService.authenticate(
                credentials,
                localStorage.getItem('accessCode')),
              timer(scalingDuration)
            );
          }),
          finalize(() => console.log('We are done!'))
        );
      }
}

参考链接:https://www.learnrxjs.io/learn-rxjs/operators/error_handling/retrywhen

0 个答案:

没有答案