如何在Angular 6中为所有根路由与子路由使用路由守卫?
在Angular 6中为根路由与子路由实现路由守卫(Route Auth Guards)
嘿,我来帮你搞定Angular 6里的路由守卫配置,不管是根路由还是嵌套的子路由,都能轻松实现权限控制。下面是一步步的具体操作方法,跟着来就行:
1. 先创建你的Auth Guard服务
首先用Angular CLI快速生成守卫文件,执行这条命令:
ng generate guard auth
CLI会提示你选择要实现的接口,直接选CanActivate和CanActivateChild(这俩分别对应根路由和子路由的守卫)。
接下来打开生成的auth.guard.ts,实现这两个接口的逻辑。这里假设你已经有一个AuthService用来管理用户登录状态,比如检查token或者用户是否已登录:
import { Injectable } from '@angular/core'; import { CanActivate, CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router'; import { Observable } from 'rxjs'; import { AuthService } from './auth.service'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate, CanActivateChild { constructor(private authService: AuthService, private router: Router) {} // 处理根路由的权限检查 canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { if (this.authService.isLoggedIn()) { return true; } // 未登录则跳转到登录页,同时记录当前路由以便登录后跳转 return this.router.createUrlTree(['/login'], { queryParams: { returnUrl: state.url } }); } // 处理子路由的权限检查,逻辑和canActivate一致,直接复用即可 canActivateChild( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { return this.canActivate(next, state); } }
对应的AuthService可以简单实现一个登录状态检查,比如:
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class AuthService { // 这里用本地存储模拟登录状态,实际项目可以用token验证 isLoggedIn(): boolean { return !!localStorage.getItem('userToken'); } }
2. 配置根路由的守卫
打开app-routing.module.ts,先导入你的AuthGuard,然后给需要保护的根路由加上canActivate属性:
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { AuthGuard } from './auth.guard'; import { DashboardComponent } from './dashboard/dashboard.component'; import { ProfileComponent } from './profile/profile.component'; import { LoginComponent } from './login/login.component'; import { RegisterComponent } from './register/register.component'; const routes: Routes = [ // 公开路由,不需要守卫 { path: 'login', component: LoginComponent }, { path: 'register', component: RegisterComponent }, // 需要保护的根路由,添加canActivate守卫 { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }, { path: 'profile', component: ProfileComponent, canActivate: [AuthGuard] }, // 默认路由跳转到dashboard { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, // 404路由 { path: '**', redirectTo: '/dashboard' } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
3. 配置子路由的守卫
子路由的守卫有两种配置方式,选哪种看你的需求:
方式一:给父路由统一配置(推荐)
如果某个父路由下的所有子路由都需要权限验证,直接在父路由上添加canActivateChild属性,这样所有子路由都会自动继承守卫,不用逐个配置:
const routes: Routes = [ // ...其他路由 { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard], // 父路由本身也需要守卫 canActivateChild: [AuthGuard], // 所有子路由继承这个守卫 children: [ { path: 'overview', component: OverviewComponent }, { path: 'settings', component: SettingsComponent }, { path: 'analytics', component: AnalyticsComponent } ] }, // ...其他路由 ];
方式二:给单个子路由配置
如果只有部分子路由需要守卫,那就单独给这些子路由加canActivate:
const routes: Routes = [ // ...其他路由 { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard], children: [ { path: 'overview', component: OverviewComponent }, // 公开子路由,不需要守卫 { path: 'settings', component: SettingsComponent, canActivate: [AuthGuard] }, // 需要守卫 { path: 'analytics', component: AnalyticsComponent, canActivate: [AuthGuard] } // 需要守卫 ] }, // ...其他路由 ];
一些关键注意事项
- 确保你的
AuthService状态是实时更新的:如果用本地存储,要注意登录/登出时同步更新;如果是用Observable(比如BehaviorSubject),守卫里要返回Observable来响应状态变化。 - 处理异步验证:如果你的登录状态需要从服务器验证(比如校验token有效性),那
canActivate和canActivateChild要返回Observable<boolean>,示例如下:canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { return this.authService.validateToken().pipe( map(isValid => { if (isValid) return true; this.router.navigate(['/login']); return false; }) ); } - 不要忘记在模块中注册服务:虽然我们用了
providedIn: 'root',但如果是旧版本Angular,可能需要手动在AppModule的providers数组中添加AuthGuard和AuthService。
内容的提问来源于stack exchange,提问作者user6299088
相关产品推荐
相关产品推荐

