Как вызвать HTTP-запрос при получении ответа другого в Angular7? - PullRequest
0 голосов
/ 15 июня 2019

Дело в том, что при вызове службы в бэкэнде, и если я получаю код ошибки, это указывает на то, что срок его действия истек, тогда во внешнем интерфейсе. Сначала: запросите действительный токен jwt.Второе: повторно запросить исходный http-запрос после получения действительного токена.Первый шаг сделан успешно, но это не так во втором.Это код перехватчика

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {


    if (!request.url.endsWith('login') && !request.url.endsWith('refreshtoken')) {
      request = this.addAuthenticationToken(request);
    }
    return next.handle(request).pipe(catchError(err => {
      Log.log("Error Status: " + err.status);
      // invalid token or bad request
      if (err.status == this.NOT_VALID_TOKEN_OR_BAD_REQUEST_ERROR_CODE) {
        this.authenticationService.logOut();
        return EMPTY;
      }
      else if (err.status == this.TOKEN_EXPIRED_ERROR_CODE) { // token is expired
        this. doRefreshToken(request, next);
      }
    }
    ));
  }

doRefreshToken(request, next) {
    return this.authenticationService.refreshToken().subscribe((resp: HttpResponse<any>) => {
      Log.log("in subscripe refresh token")
      Log.log(resp.headers.get(this.AUTH_HEADER));
      StorageManagementUtil.setLocaltStorage(resp.headers.get(this.AUTH_HEADER), <PortalRsponseTransaction>resp.body);
    },
      (error) => { Log.log(error) },
      () => {
        Log.log("on complete()")
        request = this.addAuthenticationToken(request);
        return next.handle(request);
      });
  }

А это служба обновления токенов

refreshToken() {
    let map = new TSMap();
    map.set(this.RQUEST_BODY_KEY_SESSION_TOKEN, StorageManagementUtil.readFromLocalStorage(StorageManagementUtil.SESSION_TOKEN));
    var requsetBody = JSON.stringify(map.toJSON());
    let request = new PortalRequestTransaction(requsetBody);
    return this.http.post<PortalRsponseTransaction>(fullURL, request, {
      observe: 'response',
      responseType: 'json'
    });
  }

А это скриншот из сетевого крана при проверке

https://i.ibb.co/vqLTLh2/1.png

Вопрос в том, почему не вызывается исходный сервис после получения токена обновления?И почему услуга звонка осуществляется дважды?(если мы игнорируем параметры типа запроса OPTIONS).

Я новичок в изучении угловых вопросов, поэтому мне хотелось бы предоставить достаточно информации для выяснения проблемы.

Ответы [ 2 ]

0 голосов
/ 17 июня 2019

Это решение вдохновлено этим ответом с использованием switchMap

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (!request.url.endsWith('login') && !request.url.endsWith('refreshtoken')) {
      request = this.addAuthenticationToken(request);
    }
    return next.handle(request).pipe(
      catchError((err) => {
        // invalid token or bad request
        if (err.status == this.NOT_VALID_TOKEN_OR_BAD_REQUEST_ERROR_CODE) {
          this.authenticationService.logOut();
          return EMPTY;
        }
        else if (err.status == this.TOKEN_EXPIRED_ERROR_CODE) {
          return this.handleRefreshToken(request, next);
        }
      })
    );
  }


  handleRefreshToken(request: HttpRequest<any>, next: HttpHandler) {

    return this.authenticationService.refreshToken().pipe(
      switchMap((tokenResp) => {
        StorageManagementUtil.setLocaltStorage(tokenResp.headers.get(this.AUTH_HEADER), <PortalRsponseTransaction>tokenResp.body);
        request = this.addAuthenticationToken(request);
        return next.handle(request);
      }),
      catchError(error => {
        if (error.status == this.NOT_VALID_TOKEN_OR_BAD_REQUEST_ERROR_CODE) {
          this.authenticationService.logOut();
          return EMPTY;
        }
      })
    );
  }
0 голосов
/ 15 июня 2019

1) 401 означает, что пользователь не авторизован, похоже, вы не отправляете в запросе правильный заголовок авторизации (Bearer {JWT-Token}).

2) Для токена обновления лучше использовать rxjs-retry , который поможет вам обрабатывать логику обновления либо при ошибке, либо по истечении срока действия

Код следует:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {


    if (!request.url.endsWith('login') && !request.url.endsWith('refreshtoken')) {
      request = this.addAuthenticationToken(request);
    }
    return next.handle(request).pipe(
    retryWhen(err => {
     if (err.status == this.TOKEN_EXPIRED_ERROR_CODE) { // token is expired
       return this. doRefreshToken(request, next);
      }
    }),
    catchError(err => {
      Log.log("Error Status: " + err.status);
      // invalid token or bad request
      if (err.status == this.NOT_VALID_TOKEN_OR_BAD_REQUEST_ERROR_CODE) {
        this.authenticationService.logOut();
        return EMPTY;
      }
      else if (err.status == this.TOKEN_EXPIRED_ERROR_CODE) { // token is expired
        this. doRefreshToken(request, next); // return an observable
      }
    }
    ));
  }

Приведенный выше фрагмент кода, при возникновении ошибки выполнит попытку, он сначала обновит токен, вернет наблюдаемое, а затем снова вызовет getAll.

...