You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用canActivate()拦截路由,防止越权访问其他用户资料

实现方案

前提准备

你需要先封装全局身份认证服务,存储当前登录用户的可信ID,避免前端伪造,示例的AuthService代码如下:

// auth.service.ts
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class AuthService {
  // 此处返回的用户ID需要是登录后从后端接口获取并缓存的可信值,不要直接取前端本地存储未校验的值
  getCurrentUserId(): string | null {
    const user = JSON.parse(localStorage.getItem('loginUser') || 'null');
    return user?.userId || null;
  }

  isLoggedIn(): boolean {
    return !!this.getCurrentUserId();
  }
}

第一步:创建canActivate路由守卫

// user-access.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from './auth.service';

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

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): boolean {
    // 1. 先校验用户是否登录
    if (!this.authService.isLoggedIn()) {
      this.router.navigate(['/login']);
      return false;
    }

    // 2. 从路由参数中获取要访问的目标用户ID
    const targetUserId = route.paramMap.get('id');
    // 3. 获取当前登录用户的ID
    const currentUserId = this.authService.getCurrentUserId();

    // 4. 比对ID,一致则放行
    if (targetUserId === currentUserId) {
      return true;
    }

    // 5. 不一致则拦截,跳转到403无权限页或者首页
    this.router.navigate(['/403']);
    return false;
  }
}

第二步:绑定守卫到目标路由

在你的路由配置文件中,给需要保护的用户资料/编辑路由添加守卫:

// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { UserEditComponent } from './user-edit/user-edit.component';
import { UserAccessGuard } from './user-access.guard';

const routes: Routes = [
  // 其他路由...
  {
    path: 'user/:id/edit',
    component: UserEditComponent,
    canActivate: [UserAccessGuard] // 绑定守卫
  }
];

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

注意事项

  • 前端路由守卫只能做第一层拦截,后端对应接口必须也要做相同的用户权限校验,避免攻击者绕过前端直接调用接口获取数据
  • 存储在前端的登录用户ID建议配合JWT校验,不要直接使用未经验证的本地存储值,防止用户手动修改本地存储伪造身份

内容的提问来源于stack exchange,提问作者Tommy Gordon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 22:57:03