角度-延迟加载条件路由



我正在构建一个应用程序,在应用程序开始时对用户进行身份验证。根据用户是否已通过身份验证,我想延迟加载一个不同的角度模块。

上下文:

app.component.ts

@Component({
template: `
<app-splash-screen *ngIf="isAuthenticating$ | async; else main"></app-splash-screen>
<ng-template #main>
<router-outlet></router-outlet>
</ng-template>
`
})
export class AppComponent implements OnInit {
readonly isAuthenticating$ = this.authFacade.isAuthenticating$;
constructor(private readonly authFacade: AuthFacade) {}
ngOnInit(): void {
this.authFacade.authenticate();
}
}

这就是我启动身份验证逻辑的地方,该逻辑在不确定的时间点完成。如果需要的话,我可以在完成Observable后选择加入。

当身份验证完成后,我将路由器出口加载到DOM。


app-routing.module.ts

const routes: Routes = [
// Lazy-load, when authentication succeeds
{
path: '',
pathMatch: 'full',
loadChildren: () => import('@my-application/secret').then(m => m.SecretModule)
},
// Lazy-load, when authentication fails
{
path: 'home',
loadChildren: () => import('@my-application/home').then(m => m.HomeModule)
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

这些是我的顶级路线。现在,我想要实现的是,当用户已经通过身份验证时,延迟加载SecretModule并显示其内容。

另一方面,当身份验证失败时,我希望将用户导航到主页并延迟加载HomeModule

现在我看到一个关于SecretModule的空白路由的问题。我可以想到的一个解决方案是,在身份验证完成后,在其他地方手动实现这种条件路由逻辑,而不是用"有角度的方式"。

你认为实现上述逻辑的最佳方法是什么?

(顺便说一句,我正在使用Angular 11(

首先,您可以添加两个保护,这样未经授权的用户就无法加载和访问您的秘密模块:

auth.guard.ts

@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanLoad {
constructor(
private router: Router,
private authService: AuthService, // I asume u got some kind of auth service written
) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree> | boolean | UrlTree {
console.log('Trying to activate admin route');
return this.checkAccess();
}
canLoad(route: Route, segments: UrlSegment[]): Promise<boolean | UrlTree> | boolean | UrlTree {
console.log('Trying to load admin  route');
return this.checkAccess();
}
private checkAccess(): Promise<boolean | UrlTree> {
return new Promise<boolean | UrlTree>(async (resolve) => {
// Do your check here if the user is authenticated
const isLoggedIn = await this.authService.isLoggedIn();
// If user is not authenticated he gets redirected to home page
resolve(isLoggedIn ? true : this.router.createUrlTree(['home']));
});
}
}

然后只需在你的秘密路线上使用你的警卫:

const routes: Routes = [
// Lazy-load, when authentication succeeds
{
path: '',
pathMatch: 'full',
loadChildren: () => import('@my-application/secret').then(m => m.SecretModule),
canLoad: [AuthGuard],
canActivate: [AuthGuard],
},
// Lazy-load, when authentication fails
{
path: 'home',
loadChildren: () => import('@my-application/home').then(m => m.HomeModule)
},
];

你可以在文档中阅读更多警惕

  • CanActivate
  • CanLoad

最新更新