Почему функция canLoad приводит к бесконечному l oop во время перенаправления? - PullRequest
0 голосов
/ 12 февраля 2020

Я использую функцию canLoad Angular в моем AuthGuard для аутентификации лениво загруженного модуля на root моего приложения.

Если пользователь не аутентифицирован, то модуль не загружается и пользователь перешел на страницу входа. Это прекрасно работает с canActivate, но приводит к бесконечному l oop во время запуска моего приложения для canLoad.

Я не уверен, где или как создается l oop, так как мой компонент аутентификации часть другого модуля, чем тот, который я пытаюсь загрузить, и перенаправление не на root. Я обнаружил похожие проблемы / статьи, но их случаи были более явными.

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
        }
    );

1 Ответ

1 голос
/ 13 февраля 2020

Порядок маршрутов в конфигурации имеет значение, и это предусмотрено проектом. Маршрутизатор использует стратегию выигрыша при первом совпадении при сопоставлении маршрутов, поэтому более конкретные маршруты c должны быть размещены выше менее определенных маршрутов c. В приведенной выше конфигурации сначала указываются маршруты с путем stati c, за которым следует пустой маршрут, соответствующий маршруту по умолчанию. Маршрут с подстановочными знаками стоит последним, поскольку он соответствует каждому URL-адресу и должен выбираться только в том случае, если сначала не найдено ни одного другого маршрута. (цитата из https://angular.io/guide/router)

...