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

Angular 15中CanActivate已弃用,如何修复Auth Guard问题?

解决Angular 15中CanActivate已弃用的问题

升级到Angular 15后,原有的类式AuthGuard实现CanActivate接口时会触发CanActivate is deprecated的错误提示,原代码如下:

原AuthGuard代码

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { ToastrService } from 'ngx-toastr';
import { AuthService } from 'src/app/features/auth/services/auth.service';
import { map } from 'rxjs/operators';

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

  constructor(private authService: AuthService, private toastr: ToastrService, private router: Router) { }
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    if (!this.authService.isLoggedIn()) {
      this.toastr.info('Please Log In!');
      this.router.navigate(['/auth']);
      return false;
    }
    // logged in, so return true
    this.authService.isLoggedIn();
    return true;
  }
}

解决办法

方法一:使用函数式守卫(Angular 15+官方推荐)

Angular 15开始推荐使用函数式守卫替代类式守卫,直接定义一个CanActivateFn类型的函数即可:

import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
import { AuthService } from 'src/app/features/auth/services/auth.service';

export const authGuard: CanActivateFn = (route, state) => {
  // 使用inject获取依赖实例
  const authService = inject(AuthService);
  const toastr = inject(ToastrService);
  const router = inject(Router);

  if (!authService.isLoggedIn()) {
    toastr.info('Please Log In!');
    router.navigate(['/auth']);
    return false;
  }
  authService.isLoggedIn();
  return true;
};

然后在路由配置中替换原来的类引用:

// 原路由配置
{
  path: 'protected',
  component: ProtectedComponent,
  canActivate: [AuthGuard] // 旧写法
}

// 修改后
{
  path: 'protected',
  component: ProtectedComponent,
  canActivate: [authGuard] // 使用函数式守卫
}

方法二:改用CanActivateChild接口(临时兼容方案)

如果暂时不想重构为函数式守卫,可以将类实现的接口从CanActivate改为CanActivateChild,该接口目前未被弃用:

import { Injectable } from '@angular/core';
import { CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { ToastrService } from 'ngx-toastr';
import { AuthService } from 'src/app/features/auth/services/auth.service';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivateChild {

  constructor(private authService: AuthService, private toastr: ToastrService, private router: Router) { }
  canActivateChild(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    if (!this.authService.isLoggedIn()) {
      this.toastr.info('Please Log In!');
      this.router.navigate(['/auth']);
      return false;
    }
    this.authService.isLoggedIn();
    return true;
  }
}

路由配置中对应改为canActivateChild:

{
  path: 'protected',
  component: ProtectedComponent,
  canActivateChild: [AuthGuard]
}

注意:官方长期规划中类式守卫会逐步被淘汰,建议优先采用函数式守卫方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:25:26