MST

星途 面试题库

面试题:Angular路由中的路由守卫如何应用于复杂权限控制场景

假设一个单页面应用有多种用户角色(如管理员、普通用户、访客),不同角色对不同页面有不同的访问权限。请阐述如何运用Angular的路由守卫(CanActivate、CanLoad等)来实现这种复杂的权限控制逻辑,并举例说明关键代码实现。
22.1万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

1. 理解路由守卫

  • CanActivate:用于决定是否可以激活某个路由,通常在导航到一个路由时触发。
  • CanLoad:用于决定是否可以加载某个路由模块,通常在路由懒加载时触发。

2. 实现步骤

  1. 创建权限服务
    • 该服务用于存储和管理用户角色及权限信息。
    • 示例代码:
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private userRole: string;

  constructor() {
    // 这里假设从本地存储或者后端获取用户角色
    this.userRole = localStorage.getItem('userRole') || 'guest';
  }

  getRole() {
    return this.userRole;
  }
}
  1. 创建路由守卫
    • CanActivate 守卫
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root'
})
export class RoleGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): boolean {
    const requiredRole = next.data['role'];
    const userRole = this.authService.getRole();
    if (requiredRole.includes(userRole)) {
      return true;
    } else {
      this.router.navigate(['/forbidden']);
      return false;
    }
  }
}
  • CanLoad 守卫
import { Injectable } from '@angular/core';
import { CanLoad, Route, Router, UrlSegment } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root'
})
export class RoleCanLoadGuard implements CanLoad {
  constructor(private authService: AuthService, private router: Router) {}

  canLoad(
    route: Route,
    segments: UrlSegment[]): boolean {
    const requiredRole = route.data['role'];
    const userRole = this.authService.getRole();
    if (requiredRole.includes(userRole)) {
      return true;
    } else {
      this.router.navigate(['/forbidden']);
      return false;
    }
  }
}
  1. 配置路由
    • 在路由配置中使用上述守卫,并指定每个路由所需的角色。
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RoleGuard } from './role.guard';
import { RoleCanLoadGuard } from './role-can-load.guard';
import { AdminComponent } from './admin/admin.component';
import { UserComponent } from './user/user.component';
import { GuestComponent } from './guest/guest.component';

const routes: Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    data: { role: ['admin'] },
    canActivate: [RoleGuard],
    canLoad: [RoleCanLoadGuard]
  },
  {
    path: 'user',
    component: UserComponent,
    data: { role: ['admin', 'user'] },
    canActivate: [RoleGuard],
    canLoad: [RoleCanLoadGuard]
  },
  {
    path: 'guest',
    component: GuestComponent,
    data: { role: ['admin', 'user', 'guest'] },
    canActivate: [RoleGuard],
    canLoad: [RoleCanLoadGuard]
  },
  {
    path: 'forbidden',
    component: // 禁止访问页面组件
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

通过上述步骤,利用Angular的路由守卫,我们可以有效地实现基于不同用户角色的复杂权限控制逻辑。在路由配置中明确每个路由所需的角色,路由守卫根据用户当前角色判断是否允许访问相应路由。