【问题标题】:"No provider for AuthGuard!" using CanActivate in Angular 2“没有 AuthGuard 的提供者!”在 Angular 2 中使用 CanActivate
【发布时间】:2016-11-07 07:16:48
【问题描述】:

编辑:显然这已经过时了,现在你在 NgModule 中的 providers 数组中提供保护。观看其他答案或官方文档以了解更多信息。

  • 组件上的引导已过时
  • provideRouter() 也已过时


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

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

我会尽量解释清楚,如果您需要更多详细信息,请随时告诉我。


我有我的 ma​​in.ts 文件,它使用以下代码引导应用程序:

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

我加载了 MasterComponent,它加载了一个 Header,其中包含允许我浏览我的应用程序的按钮,并且它现在还包含我的 main。

我正在按照指南使我的应用程序以相同的方式工作,使用以下 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];

我的主组件有自己的路由定义,其中还包含我要设置的守卫。 ma​​ster.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)时,我得到 没有 AuthGuard 提供程序! 错误。

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

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

【问题讨论】:

  • 您是否将AuthGuard 导入master.routes.tslogin.routes.ts
  • 是的,我确实正确导入了它们。我没有提到它,但我手动导航到该路线,因为我想使用 this.router.navigate(['/dashboard']); 链接一个
  • 奇怪的是我公司的防火墙实际上阻止了 plunkr 链接,所以我可能需要一点时间......我希望用一个正常工作的 plunkr 编辑此评论
  • 不客气。很高兴听到你想通了。

标签: authentication angular angular2-routing


【解决方案1】:

实际上,这只是导入中的一个错字...

我在打字

从'./../Authentification/auth.guard'导入{AuthGuard};

而不是

从'./../authentification/auth.guard'导入{ AuthGuard};

使其无法正常工作,但同时没有向我显示任何错误...

(悲伤的脸)

【讨论】:

  • 这就是为什么推荐使用像 Visual Studio Code 这样的 typescript 感知编辑器(它是最好的)。
  • 是的,我一直在使用 VS 2015,但显然,它不如 Visual Code。
  • 我遇到了同样的问题,最后发现问题是导入路径区分大小写
【解决方案2】:

对于那些仍然有此错误的人 - 不要忘记将您的 AuthGuard 服务或类包含到主引导函数中。 并且不要忘记在引导运行之前导入此服务。

import { bootstrap } from '@angular/platform-browser-dynamic';

import { AppComponent } from './app.component';
import { AuthGuard } from './shared/auth.service';

bootstrap(AppComponent, [
  appRouterProviders,
  AuthGuard
]);

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

【讨论】:

    【解决方案3】:

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

    我们只需要在对应于相应路由的模块中提供 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{}    
    

    【讨论】:

    • 你错过了 AuthGuard
    【解决方案4】:

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

    我将 AuthGuard 添加到我的主要路线之一,而不是像教程所示的子路线。

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

    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 添加到提供程序,不知道为什么。

    【讨论】:

    • 你拯救了我的一天!
    • 有趣的是,我不需要为提供程序添加保护,而且我正在阅读的书籍要求,我不知道为什么我的应用程序没有它也能正常工作!这就是为什么我发现了这个问题,我的应用程序有效,并且我没有添加到提供程序,我正在使用延迟加载。
    【解决方案5】:

    另外,不要陷入在路由配置中为保护类使用文字的陷阱,因为某些博客文章会这样做:

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

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

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

    另外提示,当延迟加载组件时,guard是在父组件的路由配置中应用的,而不是在延迟加载组件的路由配置中。

    【讨论】:

    • 我把 WhatEverGuard 放在单引号中,它显示没有提供者 .. 太烦人了
    • 我也是。我有: canActivate: [ 'AuthGuard', AuthGuard ] 只要我删除了它的文字。
    • 天哪,你这个天才!感谢您的回答,我所遵循的愚蠢教程使用的单引号与您描述的完全一样!
    【解决方案6】:

    您可以尝试在该模块的提供者中导入 AuthGuard,然后也将其导入路由 component-routing.module.ts 文件中

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

    【讨论】:

      【解决方案7】:
      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;
          }
      }
      

      【讨论】:

        【解决方案8】:

        我在学习教程时遇到了这个问题。我在这里尝试了大部分答案,但没有取得任何成功。然后我尝试了一种愚蠢的方法,比如将 AuthGuard 放在提供程序中的其他服务之前,它可以工作。

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

        【讨论】:

          【解决方案9】:

          答案在教程的后面。请参阅“里程碑 5:Route Guards”中“无组件路由:...”部分下的“添加 LoginComponent”主题中的文件列表。它显示 AuthGuard 和 AuthService 被导入并添加到 login-routing.module.ts 中的 providers 数组中,然后将该模块导入到 app.module.ts 中。

          登录路由.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
            ],
            ...
          

          【讨论】:

          • 谢谢你,我被困在教程上,这对我很有帮助。我认为它们应该在 appModule 中,但它们不在代码的最终版本中,没有它们我无法弄清楚它是如何工作的。
          【解决方案10】:

          同时导入 HttpModuleHttpClientModule 对我有帮助。

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

          【讨论】:

            【解决方案11】:

            尝试添加

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

            【讨论】:

              【解决方案12】:

              当我错误地设置我的路线时,这发生在我身上:

              错误

              const routes: Routes = 
              [
                { 
                  path: 'my-path', 
                  component: MyComponent, 
                  resolve: { myList: MyListResolver, canActivate: [ AuthenticationGuard ] } 
                },
              ];
              

              请注意,在这种情况下,canActivate 意外地成为了 resolve 对象的一部分。

              正确

              const routes: Routes = 
              [
                { 
                   path: 'my-path', 
                   component: MyComponent, 
                   resolve: { myList: MyListResolver }, 
                   canActivate: [ AuthenticationGuard ] 
                },
              ];
              

              【讨论】:

                猜你喜欢
                • 2017-05-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-12-20
                • 2015-07-26
                • 2018-01-09
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多