Search code examples
angularrouteslazy-loadingangular-routing

Angular 8 Routing w/ Lazy Loading modules, child within a child route can skip parent route to access child


I have the following simple structure in my application that I am trying to work with:

/
/home
/admin
    /setup
    /other

I have the router using modules and lazy loading. So the administrator page (/admin) of my application controls the access to the subpages for setting up the application. Eventually, the Admin route (/admin) will be route guarded, but right now I am just building the empty templates and some simple tests for the routing. This is all working. Bad addresses are captured, missing addresses routing to /, etc.

My problem is in protecting my addressing so that people cannot bypass the true routes of the application and get to pages they should not see. Go to /setup instead of /admin/setup.

Trying to keep things self contained, I did not want to rely on route guards on all the submodules, just the routing under a page that is guarded. This way, new modules loaded under the admin page will automatically be protected, in case a developer forgets to add the guard. Also, the individual feature modules have their own routing, so this is not in one central location as most examples use.

The code works properly going to /admin/setup, /admin/set will go to the / root. The problem I am having is that /setup also goes to the lazy loaded module for the Setup, which is a child of the Admin module routing.

EDIT: Update the routing modules based on suggestions, but the issue is still present.

app-routing.module.ts

const routes: Routes = [
    { path: '', component: DashboardComponent },
    { path: 'home', component: HomeComponent },
    { path: 'admin', loadChildren: () => import('./administrator/administrator.module').then(m => m.AdministratorModule) },

    { path: '**', redirectTo: '/' }     // Wrong route entered, return to main route
];

@NgModule({
    exports: [RouterModule],
    imports: [
        RouterModule.forRoot(routes)
    ]
})

admin-routing.module.ts

const routes: Routes = [
    { path: '', component: AdministratorComponent,
        children: [
            { path: 'setup', loadChildren: () => import('./setup/setup.module').then(m => m.SetupModule) },
            { path: 'zzz', loadChildren: () => import('./zzz/zzz.module').then(m => m.zzzModule) }
        ]
    }
];

@NgModule({
    imports: [RouterModule.forChild(routes)],
    exports: [RouterModule]
})

EDIT #2: Add example import of the Administrator routing in admin.module.ts.

admin.module.ts

@NgModule({
    declarations: [AdministratorComponent],
    imports: [
        CommonModule,
        MaterialModule,
        SetupModule,
        zzzModule,
        AdministratorRoutingModule
    ]
})
export class AdministratorModule { }

The problem is that I can go through properly to /admin/setup. However, you can also get to this page by simply going to /setup. I do not want someone to be able to bypass the routing and get to restricted pages.

I am not sure how to protect against this route (/setup) working.


Solution

  • Hello I'm not sure I understand well your problem and I don't understand your admin routes too.

    If I read your routes, I expect you have this routes:

    • /
    • /home
    • /admin/admin (because you have admin in parent and admin in child)
    • /admin/setup
    • /admin/zzz

    But I don't understand the './' before your routes. It can be the problem.

    Did you try something like that ? (This is valid if you have a router-outlet into your AdministratorComponent too)

    admin-routing.module.ts

    const routes: Routes = [
        {
            path: '',
            component: AdministratorComponent,
            children: [
                { path: 'setup', loadChildren: () => import('./setup/setup.module').then(m => m.SetupModule) }
                { path: 'zzz', loadChildren: () => import('./zzz/zzz.module').then(m => m.zzzModule) }
            ]
        }
    ]; 
    

    admin.module.ts

    @NgModule({
        declarations: [AdministratorComponent],
        imports: [
            CommonModule,
            MaterialModule
            AdministratorRoutingModule
        ]
    })
    export class AdministratorModule { }
    

    If you import modules here, you will note use lazy-load and you will add routes in current module.