вызов API в canAcitvate - Angular

Я пытаюсь работать с охранниками Auth в angular. У меня есть httpcall, который устанавливает значение true/false на основе ответа на HTTP-вызов. Проблемы: 1) httpClients возвращают наблюдаемое 2) подписка httpClient должна произойти до того, как будет вызван авторизованный метод, таким образом, hasSessionFlag уже установлен.

ДВОЙНАЯ СЛУЖБА .TS

hasSession() {
    return this.http.get<{}>('API CALL', {
      withCredentials: true,
      observe: 'response'
    }).subscribe((res=>{
      if(res.status === 200) {
        this.hasSessionFlag = true;
      } else {
        this.hasSessionFlag = false
      }
    }));
  }

//Check if all the logical conditions of the user sessions pass*
  isAuthorized(): boolean {
      if (this.hasSessionFlag) {
        this.authService.login();
      } else {
        this.dualLoginRedirect();
      }
  }

  canActivate(): boolean {
    return this.isAuthorized();
  }

МАРШРУТИЗАТОР.ТС

   {
      canActivate: [DualLogonService],
      path: 'test',
      component: TestPageComponent
    }

person devpato    schedule 24.06.2019    source источник
comment
Вы много работаете в императивном стиле кодирования, которого легко добиться, применив реактивный стиль кодирования. Может быть лучший способ добиться того же, если вы могли бы поделиться кодом this.isUserLoggedIn() и this.isInternal() или дать представление о том, что он делает. Кстати, возвращаемый тип canActivate может быть Observable‹boolean›, поэтому вы также можете составить свой наблюдаемый объект httpClient и спроецировать его на возврат логического значения и, наконец, вернуть этот наблюдаемый объект из canActivate.   -  person user2216584    schedule 25.06.2019
comment
@ user2216584 Я обновил свои вопросы. Я просто упростил это, но как тогда защита авторизации может подписаться на canActivate?   -  person devpato    schedule 25.06.2019
comment
пожалуйста, посмотрите мой ответ. Заметьте, мои предположения. Если мое предположение неверно, дайте мне знать правильное предположение. Я буду обновлять код соответственно.   -  person user2216584    schedule 25.06.2019


Ответы (2)


Согласно вашему последнему коду, я думаю, это то, что вы хотите сделать:

Если API возвращает статус 200, вы хотите вызвать «this.authService.login();», иначе «this.dualLoginRedirect();»

[Согласно вашему коду на момент написания этого ответа - ваш метод isAuthorized() не возвращает логическое значение, а возвращает неопределенное значение. Он должен возвращать логическое значение или наблюдаемое логическое значение или обещание. Я предполагаю, что в случае статуса 200 он вернет true, иначе он вернет false]. При таком предположении у вас может быть только canActive() метод:

canActive(): Observable<boolean> {
    return this.http.get<{}>('API CALL', {
              withCredentials: true,
              observe: 'response'
            })
            .pipe(
              map(res => {
                if(res.status === 200) {
                  //OR DO here whaterevr you want to do
                  this.authService.login();
                  //return true will render the associated component
                  //i.e. pass the guard
                  return true;
                } else {
                  this.dualLoginRedirect();
                  //return false will fail the guard.
                  return false;
                }
              })
            );
  }

Ваша защитная служба автоматически подпишется на возвращенный наблюдаемый метод canActivate().

Также обратите внимание, что в этом подходе члены класса не объявляются. Хотя, если ваша защита нуждается в этом, просто объявите их и используйте в соответствии с вашими требованиями.

person user2216584    schedule 24.06.2019
comment
очень круто, вопрос .... так что я понял, что моя служба защиты авторизации достаточно умна, чтобы подписаться на мой наблюдаемый, когда я добрался до маршрута x, у которого есть canActive? - person devpato; 25.06.2019
comment
@PatricioVargas Да! Вы абсолютно правы, canActiavte() угловой защиты должен возвращать Observable‹boolean | Дерево URL› | Обещание‹логическое | Дерево URL› | логический | UrlTree, чтобы пройти/не пройти охрану. Если он возвращает Observable, он автоматически подписывается на развертывание логического значения. Как разработчик, вам не нужно ничего делать. См.: angular.io/api/router/CanActivate. - person user2216584; 25.06.2019
comment
это работает, но у меня есть вопросы. Когда активация возвращает false, она переводит меня на страницу B, а затем возвращает меня на страницу A, где я был. Я не должен переходить на страницу Б, если это ложь. Это потому, что он ожидает завершения наблюдаемого? - person devpato; 25.06.2019
comment
@PatricioVargas - я не знаю, что делают this.authService.login() и this.dualLoginRedirect();. Но у охранника есть только одна ОТВЕТСТВЕННОСТЬ — может ли пользователь перейти на запрошенный URL? Если ваша логика защиты возвращает false, это означает, что вы должны перенаправить пользователя куда-то [т.е. Страница, которая информирует пользователя о том, что вам не разрешен доступ к этой странице ИЛИ странице входа]. Если true, то ваш компонент будет отображаться в соответствующем маршрутизаторе-выходе. Из вашего комментария видно, что this.dualLoginRedirect(); метод имеет логику, которая перемещает приложение на страницу B. продолжить в следующем комментарии.... - person user2216584; 25.06.2019
comment
Возврат false означает, что путь запроса недоступен. Это НЕ связано с ожиданием завершения наблюдаемого объекта. Это связано с тем, что делает метод this.dualLoginRedirect();. - person user2216584; 25.06.2019
comment
Я удалил this.dualLoginRedirect();, потому что думал, что это проблема, и на самом деле он мне больше не нужен, но проблема продолжает возникать. Позвольте мне проверить, работает ли комментирование this.authService.login() - person devpato; 25.06.2019

Вместо того, чтобы подписываться на ваш http-вызов, вы можете нажать и установить значение для hasSessionFlag... так что сделайте это..

hasSession() {
    return this.http.get<{}>('API CALL', {
      withCredentials: true,
      observe: 'response'
    }).pipe(
      tap(res=>{
      if(res.status === 200) {
        this.hasSessionFlag = true;
      } else {
        this.hasSessionFlag = false
      }
    }))
  .switchMap(res=>{
      if(this.hasSessionFlag)return this.authService.login();
      else return this.dualLoginRedirect();
}));
  }

isAuthorized(): boolean {
      if (this.hasSessionFlag) {
        this.authService.login();
      } else {
        this.dualLoginRedirect();
      }
  }

предполагая, что ваши authService.login() и dualLoginRedirect() являются наблюдаемыми

person Ajay Reddy    schedule 24.06.2019
comment
конечно... вам придется импортировать оператор крана из rxjs/operators - person Ajay Reddy; 25.06.2019
comment
Вопрос, как будет запускаться hasSession()? или где мне нужно это назвать? - person devpato; 25.06.2019