web-dev-qa-db-fra.com

"Aucun fournisseur pour AuthGuard!" Utilisation de CanActivate dans Angular 2

EDIT: Évidemment, c'est obsolète, maintenant vous fournissez votre garde au tableau providers dans un NgModule. Regardez les autres réponses ou la documentation officielle pour plus d'informations.

  • le démarrage sur un composant est obsolète
  • provideRouter() est également obsolète


J'essaie de configurer l'authentification dans mon projet, en utilisant un identifiant et AuthGuard à partir du guide Angular2: https://angular.io/docs/ts/latest/guide/router.html

J'utilise la version "@ angular/router": "3.0.0-beta.1".

Je vais essayer d'expliquer le plus possible, n'hésitez pas à me dire si vous avez besoin de plus de détails.


J'ai mon fichier main.ts qui booste l'application avec le code suivant:

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

Je charge le MasterComponent, qui charge un en-tête contenant des boutons qui me permettent de naviguer dans mon application et qui contient également mon principal pour l'instant.

Je suis le guide pour que mon application fonctionne de la même manière, avec le app.routes.ts suivant: 

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

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

Et le login.routes.ts du guide, qui définit mon AuthGuard: 

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

export const AUTH_PROVIDERS = [AuthGuard, AuthService];

mon composant maître a sa propre définition de route, qui contient également la garde que je tente de configurer. master.routes.ts:

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

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

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

Et j'utilise les mêmes fichiers que le guide, à savoir auth.guard.ts, auth.service.ts, login.component.ts et login.routes. ts.


Dans mon fichier header.component.ts, lorsque j'essaie d'accéder à des itinéraires, tout fonctionne correctement, mais lorsque j'essaie d'accéder au chemin surveillé (/ dashboard), je reçois le fournisseur No pour AuthGuard! Erreur.

J'ai vu le billet récent avec le même problème que le mien ( NoProviderError utilisant CanActivate dans Angular 2 ), mais pour moi, la garde est correctement bootstrapée jusqu'au fichier main.ts. itinéraires devraient être fournis avec le droit AuthGuard?

Toute aide ou conseil serait grandement apprécié. Merci !

26
Alex Beugnet

En fait, ce n'était qu'une faute de frappe dans une importation ...

Je tapais 

importer {AuthGuard} de './../Authentification/auth.guard';

au lieu de 

importer {AuthGuard} de './../authentification/auth.guard';

ce qui ne marche pas mais en même temps ne me montre aucune erreur ...

(visage triste)

5
Alex Beugnet

J'ai eu le même problème après avoir parcouru la section Route Guards du didacticiel Routage et autorisation du site Web Angular https://angular.io/docs/ts/latest/guide/router.html , il s'agit de la section 5. 

J'ajoute AuthGuard à l'un de mes itinéraires principaux et non à des itinéraires enfants, comme le montre le didacticiel.

Je l'ai corrigé en ajoutant AuthGuard à ma liste de fournisseurs dans mon fichier app.module.ts, de sorte que ce fichier ressemble maintenant à ceci:

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

J'ai parcouru le didacticiel et, dans leur fichier app.module.ts, ils n'ajoutent pas AuthGuard aux fournisseurs, sans savoir pourquoi.

52

En outre, ne tombez pas dans le piège consistant à utiliser un littéral pour la classe guard dans votre configuration de routage, simplement parce que certains articles de blog le font:

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

ne va pas fonctionner (No provider for...), utilisez plutôt la classe directement:

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

Autre astuce, lors du chargement paresseux de composants, la protection est appliquée dans la configuration de routage du composant parent, et non dans la configuration de routage du composant chargé paresseux.

15

Pour ceux qui ont encore cette erreur, n'oubliez pas d'inclure votre service AuthGuard ou votre classe à la fonction d'amorçage principale . Et n'oubliez pas d'importer ce service avant l'exécution du démarrage.

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

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

bootstrap(AppComponent, [
  appRouterProviders,
  AuthGuard
]);

L'équipe angulaire 2 ne l'a pas mentionné dans la documentation principale du routeur, et il m'a fallu quelques heures pour le comprendre.

9
Roman Gusiev

La réponse est plus bas dans le tutoriel. Consultez les listes de fichiers dans la rubrique "Ajouter le composant de connexion" dans la section "Itinéraire sans composant: ..." dans "Jalon 5: Route Guards". Il indique que AuthGuard et AuthService sont importés et ajoutés au tableau de fournisseurs dans login-routing.module.ts, puis que le module est importé dans app.module.ts.

login-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
  ],
  ...
6
unqualified

J'ai rencontré ce problème lorsque je suivais un tutoriel. J'ai essayé la plupart des réponses ici, mais sans succès. Ensuite, j'ai essayé de manière idiote de mettre AuthGuard avant les autres services du fournisseur et cela fonctionne.

// app.module.ts

 .. 
 providers: [
   AuthGuard,
   UserService,
   ProjectService
  ]
2
christian crisologo
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;
    }
}
1
Shailesh kala

Depuis que vous avez trouvé la solution car elle était due à un problème de syntaxe. Je voulais juste partager cette information.

nous devons fournir AuthGaudSerivce en tant que fournisseur uniquement dans le module correspondant à la route correspondante. Pas besoin de fournir dans le module principal ou le module racine car le module principal chargera automatiquement tous les sous-modules donnés. Cela aide à garder le code modulaire et encapsulé.

par exemple, supposons que nous ayons le scénario ci-dessous

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 

Ci-dessous se trouve juste un prototype, pas le code réel pour comprendre le but

//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
Vikash

Importer à la fois HttpModule et HttpClientModule m'a aidé.

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

Essayez d'ajouter 

@Injectable({ providedIn: 'root' }) no n'a pas besoin d'ajouter au fournisseur de module.

0
Ryan Huang

vous pouvez essayer d'importer AuthGuard dans le fournisseur de ce module, puis de l'importer également dans le fichier de routage composant-routing.module.ts

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