## 一、啥是路由守卫
咱先说说啥叫路由守卫哈。在 Angular 里,路由守卫就像是小区门口的保安,负责检查你有没有资格进入某个页面。它能在用户访问特定路由之前或者之后,执行一些逻辑判断,比如检查用户有没有登录,有没有相应的权限。咱们用它,主要就是用来控制页面访问,让合适的人去合适的地方。
## 二、为啥要用路由守卫
1. 页面权限管理
想象一下,公司的内部系统,有些页面只有管理员才能看,普通员工进去看了那还得了。这时候路由守卫就能派上用场啦,它能判断用户角色,只有管理员才能访问对应页面。
2. 登录验证
不少网站,你没登录就想访问一些个人中心之类的页面,肯定不行。路由守卫就能拦住你,先让你去登录页面登录了再说。
三、路由守卫的类型及示例
1. CanActivate
这个守卫是最常用的,它决定用户能不能激活某个路由。咱来看个例子(Angular 技术栈):
// 引入必要的模块
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
// 构造函数注入服务和路由
constructor(private authService: AuthService, private router: Router) {}
// 实现 CanActivate 接口的方法
canActivate(): boolean {
// 调用 AuthService 的 isLoggedIn 方法判断用户是否登录
if (this.authService.isLoggedIn()) {
return true; // 已登录,允许访问
}
// 未登录,导航到登录页面
this.router.navigate(['/login']);
return false;
}
}
在上面的代码里,AuthGuard 实现了 CanActivate 接口,canActivate 方法会检查用户是否登录。如果登录了就返回 true,允许访问;没登录就导航到登录页面,返回 false。
2. CanActivateChild
这个守卫和 CanActivate 类似,不过它是用来保护子路由的。看个例子:
import { Injectable } from '@angular/core';
import { CanActivateChild, Router } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class ChildAuthGuard implements CanActivateChild {
constructor(private authService: AuthService, private router: Router) {}
canActivateChild(): boolean {
if (this.authService.isLoggedIn()) {
return true;
}
this.router.navigate(['/login']);
return false;
}
}
3. CanDeactivate
这个守卫是在用户离开某个路由的时候起作用。比如用户在表单里填了一半信息,想离开,咱可以用这个守卫提示用户保存数据。示例如下:
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { MyFormComponent } from './my-form.component';
@Injectable({
providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<MyFormComponent> {
canDeactivate(component: MyFormComponent): boolean {
// 检查表单是否有未保存的更改
if (component.hasUnsavedChanges()) {
return confirm('你有未保存的更改,确定要离开吗?');
}
return true;
}
}
4. Resolve
Resolve 守卫会在路由激活之前预先获取数据。比如在进入一个商品详情页之前,先把商品信息从服务器取回来。看代码:
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { ProductService } from './product.service';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ProductResolver implements Resolve<any> {
constructor(private productService: ProductService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
// 获取路由参数中的商品 ID
const productId = route.paramMap.get('id');
// 调用 ProductService 的 getProduct 方法获取商品信息
return this.productService.getProduct(productId);
}
}
四、应用场景
1. 后台管理系统
在后台管理系统里,不同角色的用户有不同的操作权限。比如管理员可以管理用户信息,普通员工只能查看部分数据。这时候就可以用路由守卫来控制不同角色能访问的页面。
2. 电商网站
电商网站里,用户没登录就不能访问购物车、个人订单等页面。用路由守卫做登录验证,能保证用户体验和数据安全。
五、技术优缺点
1. 优点
- 提高安全性:能防止未授权用户访问敏感页面,保护系统数据安全。
- 提升用户体验:可以在访问页面之前就进行验证,避免用户进入页面后才发现没权限。
- 代码可维护性好:把权限验证和路由逻辑分开,代码结构更清晰。
2. 缺点
- 增加开发复杂度:需要额外编写守卫代码,处理各种验证逻辑。
- 性能开销:每次路由切换都要执行守卫逻辑,可能稍微影响性能。
六、注意事项
1. 异步操作
如果在守卫里有异步操作,比如从服务器获取用户权限信息,要处理好异步结果。可以返回一个 Observable 或者 Promise。
2. 错误处理
在守卫逻辑里要做好错误处理,避免因为某个验证步骤出错导致整个应用崩溃。
七、文章总结
在 Angular 项目里,路由守卫是个很实用的工具,能帮助咱们优雅地处理页面权限和登录验证。不同类型的守卫能满足各种场景的需求。虽然它有一些开发复杂度和性能开销,但带来的安全和用户体验提升是很值得的。在使用的时候,要注意异步操作和错误处理,这样才能让咱们的应用更加稳定和安全。
评论