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