为什么canLoad函数在重新路由期间导致无限循环?

问题描述 投票:0回答:1

我在AuthGuard中使用Angular的canLoad函数来验证应用根目录上的延迟加载模块。

如果用户未通过身份验证,则不会加载模块,并且用户会导航到登录页面。 canActivate可以很好地工作,但是在我的canLoad应用程序启动期间会导致无限循环。

我不知道在哪里或如何生成循环,因为我的auth组件是另一个模块的一部分,而我正在尝试加载的模块不属于该模块,因此重定向不是到根目录。我发现了类似的问题/文章,但他们的案件更为公然。

AppRoutingModule

const routes: Routes = [
{
    path: '',
    component: AdminLayoutComponent,
    canLoad: [AuthGuard],
    loadChildren: () => import('./_layouts/admin-layout/admin-layout.module').then(mod => mod.AdminLayoutModule)
},
{
    path: 'login',
    component: AuthComponent
},
{
    path: '404',
    component: PageNotFoundComponent,
}
];

AuthGaurdService

    @Injectable({
    providedIn: 'root',
})
export class AuthGuard implements CanActivate, CanLoad {
    constructor(private router: Router, private userService: UserService) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        return this.userService.isAuthenticated.pipe(take(1)).map(auth => {
            if (auth == true) {
                return true;
            }
            console.warn('User not authenticated. ACCESS DENIED.');
            // navigate to login page
            this.router.navigate(['/login']);
            // you can save redirect url so after authing we can move them back to the page they requested
            return false;
        });
    }

    canLoad(route: Route, segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
        return this.userService.isAuthenticated.pipe(take(1)).map(auth => {
            if (auth == true) {
                return true;
            }
            console.warn('User not authenticated. ACCESS DENIED.');
            // navigate to login page
            this.router.navigate([route.path + '/login']);
            // you can save redirect url so after authing we can move them back to the page they requested
            return false;
        });
    }
  }

AuthComponent SubmitMethod

    submitForm(): void {
    this.isSubmitting = true;
    this.errors = {errors: {}};

    const credentials = (this.authType == 'login' ? this.loginForm.value : this.registerForm.value);
    this.userService
        .attemptAuth(this.authType, credentials).subscribe(
        data => {
            console.log('Redirecting to profile');
            // Make profile default
            this.router.navigateByUrl('/profile');
        },
        err => {
            console.log('ERROR: ', err);
            this.errors = err;
            this.isSubmitting = false;
            // Redirect back to register/login
        }
    );
angular typescript authentication lazy-loading infinite-loop
1个回答
0
投票

路由在配置中的顺序很重要,这是设计使然。路由器在匹配路由时使用“先赢”策略,因此应将更具体的路由放置在不那么具体的路由之上。在上面的配置中,首先列出具有静态路径的路由,然后是与默认路由匹配的空路径路由。通配符路由排在最后,因为它与每个URL匹配,并且仅当没有其他路由最先匹配时才应选择通配符路由。(引自https://angular.io/guide/router

© www.soinside.com 2019 - 2024. All rights reserved.