Angular маршрутизатор активирует неправильную охрану маршрута - PullRequest
0 голосов
/ 06 февраля 2020

У меня проблемы с Angular маршрутизацией, которые, кажется, не имеют особого смысла. При следующей настройке этот результат происходит ...

  • Загрузка приложений по пути /
  • Запуск проверки подлинности
  • Защита проверки подлинности возвращает ложь еще не является JWT в хранилище
  • Перенаправление на /login работает должным образом.

Однако ...

  • Перейдите непосредственно к /activate (Маршрут в модуле учетной записи)
  • Консоль регистрирует, что запускается защита аутентификации (чего не должно быть)
  • Перенаправлено на /login

I Я пытаюсь понять, почему Auth Guard работает для маршрута /activate, когда он не является дочерним элементом макета панели управления.

Маршруты приложений

 {
    path: '',
    component: DashboardLayoutComponent,
    canActivate: [AuthGuard],
    canActivateChild: [DashboardGuard],
    children: [
      {
        path: 'schedule',
        loadChildren: () =>
          import('@libs/schedule').then(
            i => i.ScheduleModule
          ),
        data: {
          breadcrumb: 'Schedule'
        }
      },
      // Other feature modules omitted
      {
        path: '',
        redirectTo: '/schedule',
        pathMatch: 'full'
      }
    ]
  }

Маршруты учетных записей

  { path: 'login', component: LoginComponent },
  { path: 'activate', component: ActivateComponent }

Auth Guard

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    private jwtService: JwtService,
    private router: Router,
    private accountService: accountService
  ) { }

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> | Promise<boolean> | boolean {

    console.log('Auth Guard Start'); // <-- This appears in console

    return this.jwtService.getToken().pipe(
      map(token => {
        if (!token) {
          this.router.navigate(['/login']);
          return false;
        }
        // Attempt to populate the user using the token.
        this.accountService.populate();
        return true;
      }),
      take(1)
    );
  }
}

Модуль приложения

@NgModule({
  declarations: [AppComponent, DashboardLayoutComponent],
  imports: [
    // .. other modules omitted
    AccountModule,
    AppRoutingModule
  ],
  providers: [AuthGuard, DashboardGuard],
  bootstrap: [AppComponent]
})
export class AppModule { }

Дополнительная информация

Это происходит только при работе в производственном режиме.

Авгурий сообщает, что /login и /activate являются братьями и сестрами маршрута /. https://imgur.com/a/CJyKu8C

@angular/core: 8.2.6

@angular/router: 8.2.6

Ответы [ 2 ]

0 голосов
/ 07 февраля 2020

Эта проблема была на самом деле вызвана моей реализацией ngrx-router, где я определял ее начальное состояние.

Первоначально начальное состояние было установлено следующим образом, как это предлагается здесь - https://github.com/ngrx/platform/issues/835#issuecomment -369592809

export const routerInitialState: fromRouter.RouterReducerState<RouterStateUrl> = {
  state: {
    url: window.location.pathname,
    queryParams: getQueryParams(window.location.search.substring(1)),
    params: {}
  },
  navigationId: 0
}

Это не будет работать в производственных сборках. Например, прямой переход к маршруту, подобному /activate, вызывает несоответствие между состоянием маршрутизатора и angular состоянием маршрутизатора, отменяя навигацию.

Правильный способ установки начального состояния маршрутизатора следующим образом: .

export const routerInitialState: fromRouter.RouterReducerState<RouterStateUrl> = {
  state: {
    url: '/',
    queryParams: {},
    params: {}
  },
  navigationId: 0
}

При initialNavigation: 'enabled' в app-routing.module состояние маршрутизатора обновляется в кратчайшие возможные сроки и синхронизируется с маршрутизатором angular.

0 голосов
/ 06 февраля 2020

На самом деле я думаю, что ключ к решению вашей проблемы заключается в следующем:

Сначала вы добавляете маршруты для учетных модулей, и, конечно, в этом модуле вы помечаете их как forChild. Затем вы добавили основной AppModuleRouts. После того, как ваше приложение было скомпилировано и запущено - etire RouterTree включает все возможные пути. Так что маршруты из AccountModule фактически стали дочерними маршрутами. Итак, насколько вы применили canActivate: [AuthGuard] на пустом маршруте - самый общий из них может быть - он срабатывает каждый раз.

...