简体   繁体   English

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

[英]“No provider for AuthGuard!” using CanActivate in Angular 2

EDIT : Obviously this is outdated, now you provide your guard at the providers array in an NgModule.编辑:显然这已经过时了,现在您在 NgModule 中的providers数组中提供保护。 Watch other answers or official documentation for more information.观看其他答案或官方文档以获取更多信息。

  • bootstrapping on a component is outdated组件上的引导已过时
  • provideRouter() is outdated as well provideRouter()也已过时


I'm trying to setup Authentication in my project, using a login and AuthGuard from the Angular2 guide : https://angular.io/docs/ts/latest/guide/router.html我正在尝试使用 Angular2 指南中的登录名和 AuthGuard 在我的项目中设置身份验证: https ://angular.io/docs/ts/latest/guide/router.html

I'm using the release : "@angular/router": "3.0.0-beta.1".我正在使用发行版:“@angular/router”:“3.0.0-beta.1”。

I'll try to explain as much as possible, feel free to tell me if you need more details.我会尽量解释清楚,如果您需要更多细节,请随时告诉我。


I have my main.ts file which boostraps the app with the following code :我有我的main.ts文件,它使用以下代码增强应用程序:

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

I load the MasterComponent, which loads a Header containing buttons that allow me to navigate through my app and it also contains my main for now.我加载了 MasterComponent,它加载了一个 Header,其中包含允许我浏览我的应用程序的按钮,它现在还包含我的 main。

I'm following the guide to make my app work the same way, with the following app.routes.ts :我正在按照指南使我的应用程序以相同的方式工作,并使用以下app.routes.ts

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

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

And the login.routes.ts from the guide, which defines my AuthGuard :指南中的login.routes.ts定义了我的 AuthGuard :

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

export const AUTH_PROVIDERS = [AuthGuard, AuthService];

my Master component has its own route definition, which also contains the guard I'm trying to setup.我的主组件有自己的路由定义,其中还包含我试图设置的守卫。 master.routes.ts : master.routes.ts

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

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

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

And I'm using the same files as the guide, which are auth.guard.ts , auth.service.ts , login.component.ts and login.routes.ts .我使用与指南相同的文件,即auth.guard.tsauth.service.tslogin.component.tslogin.routes.ts


In my header.component.ts file, when I try to access any routes, it's working just fine, but when I try to access the guarded path (/dashboard), I get the No provider for AuthGuard!在我的header.component.ts文件中,当我尝试访问任何路由时,它工作得很好,但是当我尝试访问受保护的路径 (/dashboard) 时,我得到了AuthGuardNo provider! error.错误。

I saw the recent post with the same issue as mine ( NoProviderError using CanActivate in Angular 2 ), but to me the guard is bootstraped correctly up to the main.ts file, so my router should know which routes should be provided with the AuthGuard right ?我看到最近的帖子与我的问题相同( 在 Angular 2 中使用 CanActivate 的 NoProviderError ),但对我来说,守卫被正确引导到main.ts文件,所以我的路由器应该知道应该为哪些路由提供 AuthGuard 权限?

Any help or advice would be greatly appreciated.任何帮助或建议将不胜感激。 Thanks !谢谢!

I had this same issue after going through the Route Guards section of Routing and Authorization tutorial on the Angular website https://angular.io/docs/ts/latest/guide/router.html , it is section 5.在浏览了 Angular 网站https://angular.io/docs/ts/latest/guide/router.html上的路由和授权教程的 Route Guards 部分后,我遇到了同样的问题,它是第 5 部分。

I am adding AuthGuard to one of my main routes and not to child routes like the tutorial shows.我将 AuthGuard 添加到我的主要路由之一,而不是像教程所示的子路由。

I fixed it by added AuthGuard to my list of providers in my app.module.ts file, so that file now looks like this:我通过将 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 { }

I have gone back through the tutorial and in their app.module.ts file, they do not add AuthGuard to the providers, not sure why.我已经回顾了教程,在他们的 app.module.ts 文件中,他们没有向提供者添加 AuthGuard,不知道为什么。

Also, don't fall into the trap of using a literal for the guard class inside your routing configuration, just because some blog articles do:另外,不要陷入在路由配置中为保护类使用文字的陷阱,仅仅因为一些博客文章这样做:

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

is not going to work ( No provider for... ), instead, use the class directly:不会工作( No provider for... ),而是直接使用该类:

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

Another hint, when lazy loading components, the guard is applied in the routing configuration of the parent component, not in the routing configuration of the lazy loaded component.另一个提示,当延迟加载组件时,guard 应用在父组件的路由配置中,而不是延迟加载组件的路由配置中。

Try to add尝试添加

@Injectable({ providedIn: 'root' }) no need to add to module provider. @Injectable({ providedIn: 'root' })不需要添加到模块提供者。

For those who still have this error - don't forget to include your AuthGuard service or class to main bootstrap function.对于那些仍然有这个错误的人 - 不要忘记将你的 AuthGuard 服务或类包含到主引导函数中。 And don't forget to import this service before bootstrap runs.并且不要忘记在引导程序运行之前导入此服务。

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

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

bootstrap(AppComponent, [
  appRouterProviders,
  AuthGuard
]);

Angular 2 team did not mention this in main router docs, and it took couple of hours for me to figure it out. Angular 2 团队在主要路由器文档中没有提到这一点,我花了几个小时才弄明白。

The answer is further down in the tutorial.答案在教程的后面。 See the file listings in the "Add the LoginComponent" topic under the "Component-less route:..." section in "Milestone 5: Route Guards".请参阅“里程碑 5:路由保护”中“无组件路由:...”部分下“添加 LoginComponent”主题中的文件列表。 It shows AuthGuard and AuthService being imported and added to the providers array in login-routing.module.ts, and then that module being imported into app.module.ts.它显示了 AuthGuard 和 AuthService 被导入并添加到 login-routing.module.ts 中的 providers 数组,然后该模块被导入到 app.module.ts 中。

login-routing.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 app.module.ts

import { LoginRoutingModule }      from './login-routing.module';

@NgModule({
  imports: [
    ...
    LoginRoutingModule,
    ...    
  ],
  ...
  providers: [
    DialogService
  ],
  ...

Actually, it was only a typo in an import...实际上,这只是导入中的一个错字...

I was typing我在打字

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

instead of而不是

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

making it not working but at the same time not displaying me any error...使它不工作,但同时不显示任何错误...

(sadface) (悲伤的脸)

I encountered this issue when I was following a tutorial.我在学习教程时遇到了这个问题。 I tried most of the answer here but not getting any success.我在这里尝试了大部分答案,但没有取得任何成功。 Then I tried the silly way like putting the AuthGuard before the other services in the provider and it works.然后我尝试了愚蠢的方法,例如将 AuthGuard 放在提供程序中的其他服务之前,并且它有效。

// app.module.ts

 .. 
 providers: [
   AuthGuard,
   UserService,
   ProjectService
  ]

Since you got the solution as it was due to syntax issue.既然你得到了解决方案,因为它是由于语法问题。 I just wanted to share this info.我只是想分享这个信息。

we need to provide the AuthGaudSerivce as provider in only that module that correspond to respective route.我们只需要在对应于相应路由的那个模块中提供 AuthGaudSerivce 作为提供者。 No need to provide in main module or root module as main module will automatically load all the given sub module.This helps in keeping the code modular and encapsulated.无需在主模块或根模块中提供,因为主模块会自动加载所有给定的子模块。这有助于保持代码模块化和封装。

for example, suppose we have below scenario例如,假设我们有以下场景

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 

Below is just prototype, not the actual code for understanding purpose以下只是原型,不是用于理解目的的实际代码

//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{}    
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;
    }
}

Importing both HttpModule and HttpClientModule helped me.导入HttpModuleHttpClientModule对我HttpClientModule帮助。

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

you can try import AuthGuard in provider of that module and then import it in the routing component-routing.module.ts file also您可以尝试在该模块的提供者中导入 AuthGuard,然后也将其导入到路由 component-routing.module.ts 文件中

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

This happened to me when I had setup my Routes incorrectly:当我错误地设置我的路线时,这发生在我身上:

WRONG

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

Note that in this case canActivate was accidentally made a part of the resolve object.请注意,在这种情况下, canActivate意外地成为resolve对象的一部分。

CORRECT正确

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM