Angular 路由守卫(Route Guards)

摘要

在我们的实际的业务开发过程中,我们经常会遇到如下需求:

  1. 需要限制某些 URL 的可访问性,例如,对于系统管理界面,只有那些拥有管理员权限的用户才能打开。
  2. 当用户处于编辑界面时,在没有保存就离开时,需要提示用户是否放弃修改。

针对以上场景,Angualr使用路由守卫(Route Guards)来实现。

路由守卫(Route Guards)

创建路由守卫

Angular CLI提供了命令行工具,可以快速创建路由守卫框架文件:ng generate guard auth。 执行后,Angular CLI会问我们需要实现哪些接口,我们直接勾选即可:

1
2
3
4
5
? Which interfaces would you like to implement? (Press <space> to select, <a> to toggle all, <i> to invert selection)
>(*) CanActivate
( ) CanActivateChild
( ) CanDeactivate
( ) CanLoad

说明:

  1. CanActivate: 控制路由是否可以激活
  2. CanActivateChild: 控制子路由是否可以激活
  3. CanDeactivate: 控制路由是否可以退出
  4. CanLoad: 控制模块(module)是否可以被加载

比较经常使用的是1、3,分别控制进入和退出。 按照上面配置,AngularCLI自动生成如下代码,return true; 替换为我们实际的代码即可。return false; 表示不允许跳转,或者取消离开当前页面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanDeactivate<unknown> {
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return true;
}
}

在canActivate方法中,我们还可以使用跳转。如页面判断是否已经登录,如果没有登录,跳转到Login页面:

1
2
this.router.navigate(['/login']);
return false;

控制路由是否可以激活

控制路由是否可以激活,需要定义在定义路由的地方,增加canActivate属性。如果需要,还可以增加data属性, 比如告诉我们的AuthGuard进入当前路由需要验证哪些权限。data属性是可选的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const routes: Routes = [
{
path: "page1",
component: Page1Component,
data: { permissions: ['YourPage1Permission'] }, // 传入参数给AuthGuard,可选
canActivate: [AuthGuard]
},
{
path: "page2",
component: Page2omponent,
data: { permissions: ['YourPage2Permission'] }, // 传入参数给AuthGuard,可选
canActivate: [AuthGuard]
}
]

控制路由是否退出(离开)

和控制路由是否可以激活类似,在路由定义出增加 canDeactivate,并制定相应的Guard守卫即可。这里不再举例

总结

  1. 通过路由守卫(Route Guards)实现控制URL的进入和离开;
  2. Angular CLI可以辅助我们创建guard文件;