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

如何在Angular中使用AuthGuard基于后端用户角色保护管理员路由

嘿,别慌!作为Angular新手,搞AuthGuard确实有点绕,但其实步骤很清晰,我一步步给你讲怎么实现管理员路由保护:

第一步:先完善你的用户服务(必须带请求头)

你的getUserProfile方法现在没带后端需要的JWT token,后端会直接返回未授权,所以先修改服务,加上Authorization请求头:

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, tap } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  // 新增:用BehaviorSubject存储当前用户信息,方便组件订阅
  private currentUserSubject = new BehaviorSubject<any>(null);
  currentUser$ = this.currentUserSubject.asObservable();

  constructor(private httpClient: HttpClient) {}

  getUserProfile(){
    // 从localStorage取出登录时存的token(假设你登录后把token存在这)
    const token = localStorage.getItem('authToken');
    // 构造请求头
    const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);
    
    return this.httpClient.get<any>('http://localhost:3000/doctors/profile', { headers }).pipe(
      // 请求成功后把用户信息存到Subject里,组件可以直接订阅用
      tap(user => this.currentUserSubject.next(user))
    );
  }

  // 方便直接获取当前用户信息
  getCurrentUser() {
    return this.currentUserSubject.value;
  }
}

第二步:创建AdminAuthGuard并实现权限逻辑

用Angular CLI生成一个Guard:

ng generate guard auth/AdminAuth

然后修改生成的admin-auth.guard.ts,实现CanActivate接口,调用用户服务检查角色:

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { UserService } from '../user.service'; // 替换成你的服务实际路径

@Injectable({
  providedIn: 'root'
})
export class AdminAuthGuard implements CanActivate {

  constructor(
    private userService: UserService,
    private router: Router // 用来跳转无权限页面
  ) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> | Promise<boolean> | boolean {
    // 调用getUserProfile获取用户角色
    return this.userService.getUserProfile().pipe(
      map(user => {
        // 角色为1就是管理员,允许访问路由
        if (user.role === 1) {
          return true;
        } else {
          // 非管理员跳转到首页(或者你指定的无权限页面)
          this.router.navigate(['/']);
          return false;
        }
      }),
      catchError(error => {
        // 请求失败(比如token过期、未登录),跳转到登录页
        this.router.navigate(['/login']);
        return of(false);
      })
    );
  }
}

第三步:在路由配置中应用Guard

打开你的路由模块(比如app-routing.module.ts),给需要管理员权限的路由加上canActivate: [AdminAuthGuard]:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AddDoctorComponent } from './add-doctor/add-doctor.component';
import { ManageDoctorsComponent } from './manage-doctors/manage-doctors.component';
import { AdminAuthGuard } from './auth/admin-auth.guard'; // 引入Guard

const routes: Routes = [
  // 普通路由...
  { 
    path: 'add-doctor', 
    component: AddDoctorComponent, 
    canActivate: [AdminAuthGuard] // 只有管理员能进
  },
  { 
    path: 'manage-doctors', 
    component: ManageDoctorsComponent, 
    canActivate: [AdminAuthGuard] // 只有管理员能进
  },
];

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

第四步:优化前端菜单的角色判断(可选但更高效)

你之前的HTML里用*ngIf="userrole==1",可以改成订阅服务里的currentUser$,不用每次都调用API:

在你的组件里:

import { Component, OnInit } from '@angular/core';
import { UserService } from '../user.service';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
  userrole: number | null = null;

  constructor(private userService: UserService) {}

  ngOnInit(): void {
    // 订阅当前用户信息,实时更新角色
    this.userService.currentUser$.subscribe(user => {
      this.userrole = user?.role || null;
    });

    // 页面刷新时重新获取用户信息(因为Subject会清空)
    if (!this.userService.getCurrentUser()) {
      this.userService.getUserProfile().subscribe();
    }
  }
}

HTML部分保持不变就行,这样菜单会根据用户角色自动显示/隐藏。

最后提醒

  • 前端的AuthGuard只是辅助保护,你已经在后端做了权限验证,这样双重保险,就算有人直接输URL也进不去(后端会拦截)
  • 确保登录后把JWT token存在localStorage/sessionStorage里,不然服务拿不到token会请求失败
  • 可以考虑添加token过期的处理,比如在catchError里判断错误码,给用户提示

内容的提问来源于stack exchange,提问作者Amir Shahzad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:54:41