2017-08-28 6 views
9

je suis confronté à la question suivante: la section personnelle qui est protégé par un AuthGuard service est chargé deux fois lorsque je navigue sur ou par actualisation du navigateur. La deuxième fois, il supprime les paramètres de requête de l'URL si j'en ai fourni. Voici ma configuration de routeur application:charges de route enfant paresseux chargé deux fois dans angulaire

const routes: Routes = [ 
    { 
    path: 'search', 
    redirectTo: '', 
    pathMatch: 'full' 
    }, 
    { 
    path: '', 
    component: BookmarksComponent 
    }, 
    { 
    path: 'tagged/:tag', 
    component: TagComponent 
    }, 
    { 
    path: 'about', 
    component: AboutComponent 
    }, 
    { 
    path: 'personal', 
    loadChildren: 'app/personal/personal-bookmarks.module#PersonalBookmarksModule' 
    } 
]; 

@NgModule({ 
    imports: [RouterModule.forRoot(routes)], 
    exports: [RouterModule] 
}) 
export class AppRoutingModule {} 

et la configuration du routeur enfant

@NgModule({ 
    imports: [RouterModule.forChild([ 
    { 
     path: '', 
     component: PersonalBookmarksComponent, 
     canActivate: [AuthGuard], 
     children: [ 
     { 
      path: '', 
      component: PersonalBookmarksListComponent 
     }, 
     { 
      path: 'new', 
      component: NewPersonalBookmarkFormComponent 
     }, 
     { 
      path: 'bookmarks/:id', 
      component: PersonalBookmarkDetailComponent 
     } 
     ] 
    } 

    ])], 
    exports: [RouterModule] 
}) 
export class PersonalBookmarksRoutingModule {} 

Le Service AuthGuard (où s'il retourne seul vrai est le même comportement):

@Injectable() 
export class AuthGuard implements CanActivate { 

    constructor(private keycloakService: KeycloakService) {} 

    canActivate() { 
    console.log('AuthGuard#canActivate called'); 

    if (this.keycloakService.isLoggedIn()) { 
     return true; 
    } else { 
     this.keycloakService.login(); 
    } 
    } 
} 

Et le modèle Navbar:

<nav class="navbar navbar-light bg-faded" id="navbar"> 
    <a class="navbar-brand" [routerLink]="['']" routerLinkActive="active"> 
    <img src="assets/logo.png" width="35" height="35" class="d-inline-block align-top" alt=""> 
    Public Bookmarks 
    </a> 
    <ul class="nav navbar-nav"> 
    <li class="nav-item"> 
     <a class="nav-link" [routerLink]="['personal']" routerLinkActive="active">Personal list</a> 
    </li> 
    <li class="nav-item"> 
     <a class="nav-link" [routerLink]="['about']" routerLinkActive="active">About</a> 
    </li> 
    <li class="nav-item"> 
     <a class="nav-link" href="http://www.codingpedia.org/tags/#codingmarks" target="_blank">Blog</a> 
    </li> 
    <li *ngIf="isLoggedIn else notLoggedIn" class="nav-item"> 
     <a class="nav-link" (click)="logout()">Logout <i class="fa fa-lock"></i></a> 
    </li> 
    <ng-template #notLoggedIn> 
     <li *ngIf="!keycloakService.isLoggedIn()" class="nav-item"> 
     <a class="nav-link" (click)="login()">Login <i class="fa fa-unlock"></i></a> 
     </li> 
    </ng-template> 
    </ul> 
</nav> 

Le projet est disponible on Github et le comportement défectueux peut être testé à https://www.codingmarks.org/personal en se connectant avec le nom d'utilisateur/passwd - [email protected]/Test_user1$

MISE À JOUR Même si je retire PersonalBookmarksComponent et déplacer AuthGuard au module PersonalBookmarks le mauvais comportement persistent encore ... les routes pour PersonalBookmarksModule ressembler à quelque chose comme ce qui suit:

const personalBookmarksRoutes: Routes = [ 
    { 
     path: 'search', 
     redirectTo: '', 
     pathMatch: 'full' 
    }, 
    { 
     path: '', 
     component: PersonalBookmarksListComponent, 
     canActivate: [AuthGuard], 
    }, 
    { 
     path: 'new', 
     component: NewPersonalBookmarkFormComponent 
    }, 
    { 
     path: 'bookmarks/:id', 
     component: PersonalBookmarkDetailComponent 
    } 

]; 

UPDATE2: L'effacement des paramètres de requête était dû à la redirection forcée lors de la connexion avec Keycloak.

Faux:

public login(): Promise<any> { 
    let options: any; 
    options = {redirectUri: environment.HOST + 'personal'}; 
    return new Promise<any>((resolve, reject) => { 
    KeycloakService.auth.login(options) 
     .success(resolve) 
     .error(reject); 
    }); 
} 

correcte:

public login(): Promise<any> { 
    return new Promise<any>((resolve, reject) => { 
    KeycloakService.auth.login() 
     .success(resolve) 
     .error(reject); 
    }); 
} 
+0

Pouvez-vous essayer d'ajouter un chemin vide non pour 'BookmarksComponent' –

+0

J'ai essayé mais j'ai eu le même comportement, pourquoi cela aiderait-il? – Adrian

Répondre

4

La raison pour laquelle les routes sont en cours de chargement est deux fois parce que vous avez spécifié le chemin du routeur pour charger deux composants quand vous allez Accédez à cette route ' '.

modifier la configuration du routeur à

@NgModule({ 
    imports: [RouterModule.forChild([ 
    { 
     path: '', 
     //component: PersonalBookmarksComponent, //either remove this component line completely [best way is to remove this component deceleration] 
     canActivate: [AuthGuard], 
     children: [ 
     { 
      path: '', // or specify a different route to this better use a redirect option on path 
      component: PersonalBookmarksListComponent 
     }, 
     { 
      path: 'new', 
      component: NewPersonalBookmarkFormComponent 
     }, 
     { 
      path: 'bookmarks/:id', 
      component: PersonalBookmarkDetailComponent 
     } 
     ] 
    } 

    ])], 
    exports: [RouterModule] 
}) 
+0

PersonalBookmarksComponent contient juste le routeur-sortie pour afficher les vues "personnelles" de l'enfant ... C'est aussi une approche prise dans le tutoriel officiel du routeur - https://angular.io/generated/live-examples/router/eplnkr.html même si je le change en non-vide (laissez l'enfant vide), ou changez le composant enfant en non-vide et laissez le chemin parent vide, le même comportement reste toujours ... Je commence à penser qu'il pourrait avoir quelque chose à faire avec keycloak js adatper – Adrian

+0

@Adrian pouvez-vous créer une petite démo répliquant ce problème dans stackblitz, car cela aurait dû fonctionner –

3

U peut effectuer les deux étapes suivantes:

  1. Déplacez le authGuard au routage du module personnel, il permettra également d'améliorer vos performances que le module ne sera pas être chargé au cas où l'utilisateur ne serait pas authentifié.
  2. Retirez le composant "PersonalBookmarksComponent" contenant une sortie de routeur vide, fournissez plutôt le routeur pour le reste de nos composants directement.

Je crois que cette approche résoudra votre problème.

Le dispositif de sécurité est appelé deux fois pour votre composant et une fois pour votre composant enfants.

+0

Hey Chirag, qui ne l'a pas fait non plus - voir la mise à jour dans ma question ... – Adrian