类型错误:guard不是一个函数。

17

我不知道是否有遗漏了一些细节,或者我做错了什么,但我找不到导致错误的原因。我的目标是每次用户访问页面中的路由时都会检查用户是否已登录。我使用的是 Angular 5。

App.module:

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './pages/autenticacao/login.component';
import { AuthService } from './auth/auth.service';
import { RoutesInterceptor } from './auth/routes.interceptor';

import * as $ from 'jquery';

@NgModule({
  declarations: [ AppComponent, LoginComponent ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,

  ],
  bootstrap: [AppComponent],
  providers: [ AuthService, RoutesInterceptor, ],
})
export class AppModule {
}

Routes.intercpetor:

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

import { AuthService } from './auth.service';

@Injectable()
export class RoutesInterceptor implements CanActivate {

constructor(private auth: AuthService) {}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    return this.auth.isUserAuthenticated();
}
}

我的路由:

import { NgModule } from '@angular/core';
import { ExtraOptions, RouterModule, Routes } from '@angular/router';

import { LoginComponent } from './pages/autenticacao/login.component';
import { RoutesInterceptor } from './auth/routes.interceptor';

const routes: Routes = [
  { path: 'pages', loadChildren: 'app/pages/pages.module#PagesModule', canActivate: [RoutesInterceptor] },
  { path: 'login', component: LoginComponent },
  { path: '', redirectTo: 'pages', pathMatch: 'full' },
  { path: '**', redirectTo: 'pages' },
];

const config: ExtraOptions = {
  useHash: true,
};

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

enter image description here


方法 guard 在哪里? - Aravind
我不确定,从我看到的来看这是Angular。它在路由器方法内部。 - Erick Zanetti
4个回答

26

导致此问题的另一个原因是如果您尝试将CanActivate守卫用作另一种类型的守卫,例如CanActivateChild


确实,在使用模拟守卫进行测试时,这就是我搞砸的地方。感谢您的提示! - Adrian Moisa
我正在为 Keycloak 守卫函数 isAccessAllowed 替换包装器,并使用自定义实现进行本地开发,但没有提供将要执行的 canActivate 方法。您的评论帮助我进入了 Keycloak 源代码并看到它实际上会执行 canActivate。 - Maxime Lyakhov
在我的情况下,我使用了CanActivateFn作为Observable而不是经典方式https://angular.io/api/router/CanActivate(在Angular 15之前)。 如果您的情况也是如此,请继续使用函数并直接注入守卫。 - Adrug

7

我修改了那部分代码,然后它就可以工作了。

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';

import { AuthService } from './auth.service';

@Injectable()
export class RoutesInterceptor implements CanActivate {

constructor(private auth: AuthService, private route: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    if (this.auth.isUserAuthenticated()) {
        return true;
    }
    this.route.navigate(['./login']);
    return false;
  }
}

如果您未登录,我忘记了进行重定向


3

RoutesInterceptor是在AppRoutingModule中使用的,而不是在您的AppModule中使用的。因此,您应该将RoutesInterceptor列为AppRoutingModule中的provider


这不太可能是答案,因为如果是真的,它会导致注入器错误。但可以将其作为有用的注释添加。 - Estus Flask
这有所帮助,但主要的是代码的更改,谢谢。 - Erick Zanetti

0
尝试在PagesModuleproviders中添加RoutesInterceptor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接