(Angular -Refre sh token) - Невозможно обновить sh токен доступа в перехватчике с помощью refre sh token - PullRequest
0 голосов
/ 07 августа 2020

Я знаю, что это довольно банальный topi c, но, просмотрев довольно много решений, я не смог обновить sh мой токен jwt после получения токена refre sh. Обработчик http, который обновляет токен, по какой-то причине даже не запускается.

PS: Я также хочу повторить неудачные запросы.

Это мой server-errors.interceptor.ts файл, который обрабатывает неаутентифицированные (401) запросы.

export class ServerErrorsInterceptor implements HttpInterceptor {
  isRefreshingToken = false;
  tokenSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null);
  subscription: Subscription = null;
  constructor(
    private route: Router,
    private toastService: ToastrService,
    private authService: AuthService,
    private http: HttpClient
  ) {}

  addToken(req: HttpRequest<any>, newToken: string): HttpRequest<any> {
    return req.clone({
      headers: req.headers.set('Authorization', `Bearer ${newToken}`),
    });
  }

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    // If the call fails, retry until 5 times before throwing an error
    return next.handle(request).pipe(
      tap(
        (event: HttpEvent<any>) => {
          if (event instanceof HttpResponse) {
            // placeholder for doing stuff  with event response
            if (event.status == 204) {
              this.toastService.error(` Wrong Credentials`, '204 Occurred', {
                positionClass: 'toast-top-center',
              });
            }
          }
        },
        (error: any) => {
          if (error instanceof HttpErrorResponse) {
            if (error.status == 401 || error.status == 403) {
              this.toastService.error(
                `${error.name}: ${error.status} ${error.statusText}`,
                '',
                { positionClass: 'toast-top-center' }
              );
              // this.authService.logout();
              // this.route.navigate(['']);
               return this.handleUnauthorized(request, next); // for token handling

            } else {
              this.toastService.error(
                error.error.message,
                `Server Error ${error.status}`,
                { positionClass: 'toast-top-center' }
              );
            }
          }
        }
      )
    );
  }

  handleUnauthorized(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<any> {
    if (!this.isRefreshingToken) {
      this.isRefreshingToken = true;

      // Reset here so that the following requests wait until the token
      // comes back from the refreshToken call.
      this.tokenSubject.next(null);
      // TODO need a logic change here
      const refreshToken = this.authService.getRefreshToken()
      const payload = {
        token: refreshToken
      }
      const url = 'http://202.166.161.218:8090/api/auth/refreshToken';
      return this.http.post<Observable<any>>(url, payload).pipe(switchMap((newToken: any) => {
        if(newToken) {
          this.authService.setAccessToken(newToken.accessToken)

          this.tokenSubject.next(newToken.accessToken);
          req = req.clone({
            setHeaders: {
              'Authorization':`Bearer ${newToken.accessToken}`
            }
          });
          return next.handle(req);
        } else {
          this.authService.logout();
        }
        this.isRefreshingToken = false;
      }),
        catchError(err => {
          this.authService.logout();
          return of(err);
        }));
      
    } else {
      return this.tokenSubject.pipe(
        filter((token) => token != null),
        take(1),
        switchMap((token) => {
          return next.handle(this.addToken(req, token));
        })
      );
    }
  }
}

Также стоит упомянуть, что я использую 3 перехватчика в следующем порядке:

app.module.ts

 {
      provide: HTTP_INTERCEPTORS,
      useClass: ApiInterceptor,
      multi: true,
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: JwtInterceptor,
      multi: true,
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: ServerErrorsInterceptor,
      multi: true,
    },

ApiInterceptor просто изменяет URL-адреса запросов, а JwtInterceptor проверяет наличие jwtToken.

Заранее спасибо.

...