Angular 4中canActivate是否支持配置项?如何基于权限控制路由访问
这个需求太合理了!完全没必要为每个权限单独写守卫,咱们搞一个通用的权限校验守卫,通过路由参数传递需要的权限,一次搞定所有场景。我给你一步步拆解实现:
第一步:创建可复用的CheckForRightGuard守卫
这个守卫会从路由配置里读取需要的权限,再和当前用户的userRights对比,判断是否允许访问:
import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router'; import { UserService } from './user.service'; // 假设你有这个用户服务,用来获取当前用户信息 @Injectable({ providedIn: 'root' }) export class CheckForRightGuard implements CanActivate { constructor(private userService: UserService, private router: Router) {} canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { // 从路由的data字段里获取需要校验的权限 const requiredRights = route.data['requiredRights'] as string[]; // 如果没指定权限,默认允许访问(或者根据你的需求改成拒绝) if (!requiredRights || requiredRights.length === 0) { return true; } // 从用户服务获取当前用户的权限(这里假设已从MongoDB加载完成) const userRights = this.userService.currentUser?.userRights || []; // 检查用户是否拥有至少一个需要的权限 // 如果你需要用户拥有所有指定权限,把some改成every即可 const hasPermission = requiredRights.some(right => userRights.includes(right)); if (!hasPermission) { // 无权限时跳转到自定义的无权限页面 this.router.navigate(['/unauthorized']); return false; } return true; } }
第二步:在路由配置中使用守卫并传递权限
给需要权限校验的路由添加data字段指定权限,同时把守卫加入canActivate数组(记得先加登录验证守卫,确保用户已登录):
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { PostEditComponent } from './post-edit/post-edit.component'; import { PostDeleteComponent } from './post-delete/post-delete.component'; import { CheckForRightGuard } from './check-for-right.guard'; import { AuthGuard } from './auth.guard'; // 你的登录验证守卫 const routes: Routes = [ { path: 'posts/edit', component: PostEditComponent, // 先验证登录,再校验权限 canActivate: [AuthGuard, CheckForRightGuard], // 指定需要的权限,支持单个或多个 data: { requiredRights: ['edit-post', 'manage-content'] } }, { path: 'posts/delete', component: PostDeleteComponent, canActivate: [AuthGuard, CheckForRightGuard], data: { requiredRights: ['delete-post'] } }, { path: 'unauthorized', component: UnauthorizedComponent // 自定义的无权限页面 } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
第三步:补充用户服务的逻辑(参考)
确保你的用户服务能正确获取当前用户的userRights(从MongoDB加载后存储):
import { Injectable } from '@angular/core'; export interface User { id: string; username: string; userRights: string[]; } @Injectable({ providedIn: 'root' }) export class UserService { currentUser: User | null = null; // 登录后调用这个方法从后端获取用户信息(包含userRights) loadCurrentUser(): void { // 实际项目中替换为HTTP请求,从MongoDB对应的表获取数据 this.currentUser = { id: '1', username: 'test-user', userRights: ['edit-post', 'view-dashboard'] }; } }
额外优化:异步权限校验
如果用户权限是异步获取的(比如刚登录时从后端拉取),可以把守卫的返回值改成Observable<boolean>:
import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; // 省略其他代码... canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { const requiredRights = route.data['requiredRights'] as string[]; return this.userService.getCurrentUser().pipe( map(user => { const userRights = user?.userRights || []; const hasPermission = requiredRights.some(right => userRights.includes(right)); if (!hasPermission) { this.router.navigate(['/unauthorized']); return false; } return true; }) ); }
内容的提问来源于stack exchange,提问作者Sithys
相关产品推荐
相关产品推荐

