首页 文章

“没有AuthGuard的提供者!”在Angular 2中使用CanActivate

提问于
浏览
25

EDIT : 显然这已经过时了,现在你在NgModule的 providers 数组中提供你的守卫 . 有关更多信息,请查看其他答案或官方文档 .

组件上的

  • bootstrapping已过时

  • provideRouter() 也已过时



我正在尝试使用Angular2指南中的登录名和AuthGuard在我的项目中设置身份验证:https://angular.io/docs/ts/latest/guide/router.html

我正在使用该版本:“@ angular / router”:“3.0.0-beta.1” .

我会尝试尽可能多地解释,如果您需要更多细节,请随时告诉我 .


我有我的 main.ts 文件,它使用以下代码来提升应用程序:

bootstrap(MasterComponent, [
    APP_ROUTER_PROVIDERS,
    MenuService
])
.catch(err => console.error(err));

我加载了MasterComponent,它加载了一个包含按钮的Header,这些按钮允许我浏览我的应用程序,它现在也包含我的主要内容 .

我正在按照指南使我的应用程序以相同的方式工作,使用以下 app.routes.ts

export const routes: RouterConfig = [
    ...LoginRoutes,
    ...MasterRoutes
];

export const APP_ROUTER_PROVIDERS = [
    provideRouter(routes),
    AUTH_PROVIDERS
];

并且指南中的 login.routes.ts 定义了我的AuthGuard:

export const LoginRoutes = [
    { path: 'login', component: LoginComponent }
];

export const AUTH_PROVIDERS = [AuthGuard, AuthService];

我的主组件有自己的路由定义,其中还包含我正在尝试设置的防护 . master.routes.ts

export const MasterRoutes : RouterConfig = [
    { path: '', redirectTo: '/accueil', pathMatch: 'full' },

    {
        path: 'accueil',
        component: AccueilComponent
    },

    { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
];

我使用与指南相同的文件,它们是 auth.guard.tsauth.service.tslogin.component.tslogin.routes.ts .


在我的 header.component.ts 文件中,当我尝试访问任何路由时,它工作得很好,但是当我尝试访问受保护的路径(/ dashboard)时,我得到 No provider for AuthGuard! 错误 .

我看到最近的帖子与我的问题相同(NoProviderError using CanActivate in Angular 2),但对我来说,警卫是正确引导到 main.ts 文件,所以我的路由器应该知道AuthGuard应该提供哪些路由?

任何帮助或建议将不胜感激 . 谢谢 !

11 回答

  • 15

    实际上,这只是一个输入错误...

    我在打字

    从'./../Authentification/auth.guard'导入;

    代替

    从'./../authentification/auth.guard'导入;

    使它不工作,但同时不显示任何错误...

    (悲伤的脸)

  • 51

    此外,不要陷入在路由配置中使用保护类的文字的陷阱,只是因为一些博客文章:

    { path: 'whatever', component: WhatEverComponent, canActivate: ['WhatEverGuard'] }
    

    不会起作用( No provider for... ),而是直接使用该类:

    { path: 'whatever', component: WhatEverComponent, canActivate: [WhatEverGuard] }
    

    另一个提示,当延迟加载组件时,防护应用于父组件的路由配置,而不是在延迟加载组件的路由配置中 .

  • 9

    在通过Angular网站https://angular.io/docs/ts/latest/guide/router.html上的路由和授权教程的Route Guards部分后,我遇到了同样的问题,它是第5部分 .

    我将AuthGuard添加到我的主要路线之一,而不是像教程节目那样添加到子路线 .

    我通过在我的app.module.ts文件中添加AuthGuard到我的提供程序列表来修复它,所以该文件现在看起来像这样:

    import { AppComponent } from './app.component';
    import {AppRoutingModule} from './app-routing.module';
    import {AuthGuard} from './auth-gaurd.service';
    
    import { AnotherPageComponent } from './another-page/another-page.component';
    import { LoginPageComponent } from './login-page/login-page.component';
    
    @NgModule({
      imports: [
        BrowserModule,
        FormsModule,
        JsonpModule,
        AppRoutingModule,
        HttpModule
      ],
      declarations: [
        AppComponent,
        LoginPageComponent,
        AnotherPageComponent
      ],
      providers: [AuthGuard],
      bootstrap: [AppComponent]
    })
    
    export class AppModule { }
    

    我已经回顾了教程并在他们的app.module.ts文件中,他们没有将AuthGuard添加到提供者,不知道为什么 .

  • 1

    对于仍有此错误的用户 - 请不要忘记将AuthGuard服务或类包含在主引导功能中 . 并且不要忘记在bootstrap运行之前导入此服务 .

    import { bootstrap } from '@angular/platform-browser-dynamic';
    
    import { AppComponent } from './app.component';
    import { AuthGuard } from './shared/auth.service';
    
    bootstrap(AppComponent, [
      appRouterProviders,
      AuthGuard
    ]);
    

    Angular 2团队在主路由器文档中没有提到这一点,我花了几个小时来弄明白 .

  • 1

    因为你得到了解决方案,因为它是由于语法问题 . 我只想分享这些信息 .

    我们需要仅在与相应路由对应的模块中提供AuthGaudSerivce作为提供者 . 无需在主模块或根模块中提供主模块将自动加载所有给定的子模块 . 这有助于保持代码模块化和封装 .

    例如,假设我们有以下情况

    1. we have module m1
    2. we have route m1r in module m1
    3. route m1r has 2 route r1 and r2
    4. we want to protect r1 using authGaurd
    5. finally we have main module that is dependent on sub module m1
    

    下面只是原型,而不是用于理解目的的实际代码

    //m1.ts    
    import {AuthGaurd} from './auth.gaurd.service'
    import {m1r} from './m1r'
        @NgModule(
         imports: [m1r],
         providers: [AuthGaurd]
        )
        export class m1{
        }
    
    //m1r.ts
    import {AuthGaurd} from './auth.gaurd.service'
    const authRoute = [
     {path: '/r1', component: 'authComponent', canActivate: [AuthGaurd]},
     {path: '/r2', component: 'other'}
    ]
    export authRoute
    
    //main.module.ts
    import {m1} from ''
    import {mainComponent} from ''
    @NgModule({
      imports: [m1],
      bootstrap: [mainComponent]
      })
    export class MainModule{}
    
  • 1

    尝试添加

    @Injectable({ providedIn: 'root' }) 无需添加到模块提供程序 .

  • 6
    import { Injectable } from '@angular/core';
    import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
    
    @Injectable()
    export class AuthGuard implements CanActivate {
    
        constructor(private router: Router) { }
    
        canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
            if (localStorage.getItem('currentUser')) {
                // logged in so return true
                return true;
            }
    
            // not logged in so redirect to login page with the return url
            this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
            return false;
        }
    }
    
  • 0

    您可以尝试在该模块的提供程序中导入AuthGuard,然后将其导入路由组件-route.module.ts文件中

    @NgModule({
    providers: [
        AuthGuard
      ],})
    
  • 5

    我在阅读教程时遇到了这个问题 . 我在这里尝试了大部分答案,但没有取得任何成功 . 然后我尝试了愚蠢的方式,比如将AuthGuard放在提供商中的其他服务之前,它就可以了 .

    // app.module.ts
    
     .. 
     providers: [
       AuthGuard,
       UserService,
       ProjectService
      ]
    
  • 2

    导入 HttpModuleHttpClientModule 对我有帮助 .

    import { HttpClientModule } from '@angular/common/http'; 
    import { HttpModule } from '@angular/http';
    
  • 0

    答案在本教程中进一步说明 . 请参阅“里程碑5:路径防护”中“无组件路径:...”部分下的“添加LoginComponent”主题中的文件列表 . 它显示正在导入AuthGuard和AuthService并将其添加到login-routing.module.ts中的providers数组中,然后将该模块导入app.module.ts .

    登录-routing.module.ts

    ...
        import { AuthGuard }            from './auth-guard.service';
        import { AuthService }          from './auth.service';
        ...
        @NgModule({
        ...
          providers: [
            AuthGuard,
            AuthService
          ]
        })
        export class LoginRoutingModule {}
    

    app.module.ts

    import { LoginRoutingModule }      from './login-routing.module';
    
    @NgModule({
      imports: [
        ...
        LoginRoutingModule,
        ...    
      ],
      ...
      providers: [
        DialogService
      ],
      ...
    

相关问题