“没有AuthGuard提供商!”在Angular 2

时间:2016-07-05 12:35:57

标签: authentication angular angular2-routing

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

  • 对组件的引导已过时
  • 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.ts auth.service.ts login.component。 ts login.routes.ts

在我的 header.component.ts 文件中,当我尝试访问任何路由时,它工作得很好,但是当我尝试访问受保护的路径(/ dashboard)时,我得到了< strong>没有AuthGuard提供商!错误。

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

非常感谢任何帮助或建议。 谢谢!

12 个答案:

答案 0 :(得分:57)

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

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

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

SELECT winningBids;
+----+-----------+----------+---------+--------------------------+------+
| id | auctionID | bidderID | amount  | bidTime                  | pr   |
+----+-----------+----------+---------+--------------------------+------+
| 10 |         3 |        1 | 5000000 | 2016-10-21 03:56:00.0000 |   60 |
|  5 |         3 |        3 |  500000 | 2016-10-18 21:59:36.0000 |   25 |
+----+-----------+----------+---------+--------------------------+------+

SELECT loosingBids;
+----+-----------+----------+---------+--------------------------+------+
| id | auctionID | bidderID | amount  | bidTime                  | pr   |
+----+-----------+----------+---------+--------------------------+------+
|  5 |         3 |        3 |  500000 | 2016-10-18 21:59:36.0000 |   25 |
|  9 |         3 |        2 |  250000 | 2016-10-20 23:54:26.0000 |   25 |
+----+-----------+----------+---------+--------------------------+------+

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

答案 1 :(得分:15)

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

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

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

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

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

答案 2 :(得分:11)

对于仍有此错误的用户 - 请勿忘记将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团队在主路由器文档中没有提到这一点,我需要花费几个小时来解决这个问题。

答案 3 :(得分:6)

答案在本教程中进一步说明。请参阅“里程碑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
  ],
  ...

答案 4 :(得分:5)

实际上,进口只是一个错字......

我正在打字

  

从&#39; ./../ Authentification / auth.guard&#39;;

导入{AuthGuard}

而不是

  

从&#39; ./../ authentification / auth.guard&#39;;

导入{AuthGuard}

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

(sadface)

答案 5 :(得分:3)

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

// app.module.ts

 .. 
 providers: [
   AuthGuard,
   UserService,
   ProjectService
  ]

答案 6 :(得分: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{}    

答案 7 :(得分:1)

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 :(得分:1)

导入HttpModuleHttpClientModule对我有帮助。

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

答案 9 :(得分:0)

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

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

答案 10 :(得分:0)

尝试添加

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

答案 11 :(得分:0)

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

错误

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 ] 
  },
];