this.router.navigate в Guard блокирует маршруты в будущем

Я установил два охранника в Angular 4: один перенаправляет пользователей на страницу входа, когда они пытаются добраться до защищенного маршрута, а другой перенаправляет пользователей на страницу приветствия с «Домашней страницы», если они еще не были там.

Сами охранники работают прекрасно... но я заметил очень странное поведение. Добавление перенаправления через this.router.navigate в защитном устройстве WelcomeTraveler переводит приложение в состояние, когда я не могу получить доступ к защищенным маршрутам из первого защитного устройства даже после входа в систему. Меня просто продолжают возвращать на домашнюю страницу. .

Вот мои охранники:

export class AuthGuardLoggedInUser implements CanActivate {
  private isLoggedIn: boolean;
  private working: boolean;
  constructor (@Inject(Store) private _store:Store<AppStore>, @Inject(Router) private _router: Router) 
  {
    _store.select(state => state.AuthNState).subscribe(auth =>
    {
      this.isLoggedIn = auth.connected
      this.working = auth.working
    })
  }
  canActivate() {
    if (this.working)
    {
      let promise: Promise<boolean>  = new Promise((resolve, reject) => {
        let sub = this._store.select(state => state.AuthNState).subscribe(auth =>
        {
          if (!auth.working) {
            resolve(auth.connected)
            sub.unsubscribe()
            if (!auth.connected) this._router.navigate(['/i/login']);
          }
        })
      });
      return promise
    }
    else if (this.isLoggedIn){
      return true
    }
    else {
      this._router.navigate(['/i/login']);
    }

export class WelcomeTraveler implements CanActivate {
  private hasAlreadyVisitedWelcomePage: boolean;
  private isLoggedIn: boolean;
  private working: boolean;
  constructor (@Inject(Store) private _store:Store<AppStore>, @Inject(Router) private _router: Router) 
  {
    _store.select(state => state.AuthNState).subscribe(auth =>
    {
      this.isLoggedIn = auth.connected
      this.working = auth.working
    })
  }
  canActivate() {
    if (this.working)
    {
      let promise: Promise<boolean> = new Promise((resolve, reject) => {
        let sub = this._store.select(state => state.AuthNState).subscribe(auth =>
        {
          if (!auth.working) {
            resolve(auth.connected)
            sub.unsubscribe()
            this.hasAlreadyVisitedWelcomePage = true
            this._router.navigate(['/i/welcome']);
          }
        })
      });
      return promise
    }
    else if (this.isLoggedIn){
      return true
    }
    else if (!this.hasAlreadyVisitedWelcomePage){
      this.hasAlreadyVisitedWelcomePage = true
      this._router.navigate(['/i/welcome']);
    }
    else return true
  }
}

А вот фрагмент таблицы маршрутизации:

export var AppRoutes = RouterModule.forRoot([
  {
    path: '',
    component: HomeComponent,
    canActivate: [WelcomeTraveler]
  }, {
    path: 'i/getstarted',
    component: GetStartedPageComponent,
    canActivate: [AuthGuardLoggedInUser]
  }, {
    path: 'i/login',
    component: LoginPageComponent
  }, {
    path: 'i/profile',
    component: ProfilePageComponent,
    canActivate: [AuthGuardLoggedInUser]
  }, {
    path: 'i/welcome',
    component: WelcomePageComponent
  }])

Само присутствие this.router.navigate в блоке WelcomeTraveler, по-видимому, вызывает проблему, даже если эти линии никогда не затрагиваются! После входа в систему меня отправляют обратно в «Домой» сразу после попытки перейти к профилю (после успешного прохождения первого охранника). Если я уберу линии навигации - проблема исчезнет.

Любые идеи?


person tcmoore    schedule 28.09.2017    source источник


Ответы (1)


Как это часто бывает, здесь я был на ложном пути. Для тех, кто мог отметить это или проголосовать за это, я бы посоветовал вам проверить любые подписки, которые у вас могут быть, которые вызывают router.navigate - в моем случае мне не удалось очистить эти подписки в моих компонентах входа/регистрации... поэтому, как только подписка была инициализирована, каждый раз, когда обновлялось состояние, меня перенаправляли на домашнюю страницу.

Исправил так:

export class LoginPageComponent implements OnDestroy {
   private _redirectSubscription: Subscription;
   constructor (private _store:Store<AppStore>, private router: Router) {
      this._redirectSubscription = _store.select((state) => state.AuthNState).subscribe((auth) =>
      {
        if (auth.connected) this.router.navigate(['']);
      })
   }

   ngOnDestroy() {
     //Called once, before the instance is destroyed.
     //Add 'implements OnDestroy' to the class.
     this._redirectSubscription.unsubscribe();
   }
}
person tcmoore    schedule 22.10.2017