簡體   English   中英

Angular 路由器激活錯誤的路由保護

[英]Angular router activates wrong route guard

我在 Angular 路由方面遇到了一些似乎沒有多大意義的問題。 通過以下設置,會發生這種結果......

  • 應用程序加載在路徑/
  • Auth 守衛運行
  • 身份驗證保護返回 false,因為存儲中還沒有 JWT
  • 重定向到/login按預期工作。

然而...

  • 直接導航到/activate (賬戶模塊中的路由)
  • 正在運行身份驗證防護的控制台日志(這不應該發生)
  • 重定向到/login

我正在努力理解為什么當它不是儀表板布局的子級時,為什么 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 }

身份驗證衛士

@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 { }

附加信息

僅在生產模式下運行時會發生這種情況。

Augury 報告說/login/activate都是/路由的兄弟。 https://imgur.com/a/CJyKu8C

@angular/core: 8.2.6

@angular/router: 8.2.6

其實我認為,你的問題的線索如下:

您首先為會計模塊添加路由,當然在該模塊中您將它們標記為 forChild。 然后,您添加了主 AppModuleRouts。 在您的應用程序被編譯並運行后 - 整個 RouterTree 包括所有可能的路徑。 這樣,來自 AccountModule 的路由實際上變成了子路由。 因此,就您在空路由上應用 canActivate: [AuthGuard] 而言 - 最通用的可能是 - 它每次都會觸發。

這個問題實際上是由我的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類的路線會導致路由器狀態和角度路由器狀態之間出現差異,從而取消導航。

top設置初始路由器狀態的正確方法如下...

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

使用initialNavigation: 'enabled'app-routing.module ,路由器狀態會在最早的可能點更新並與角度路由器同步。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM