Le routage Angular2 peut activer et AuthGuard (JWT) avec paramètre de rôle utilisateur

Dans ce projet exaple avec authentification JWT, nous pouvons vous permettre d'autoriser uniquement les utilisateurs authentifiés vers certains itinéraires:

import { RouterConfig } from '@angular/router'; import { Home } from './home'; import { Login } from './login'; import { Signup } from './signup'; import { AuthGuard } from './common/auth.guard'; export const routes: RouterConfig = [ { path: '', component: Login }, { path: 'login', component: Login }, { path: 'signup', component: Signup }, { path: 'home', component: Home, canActivate: [AuthGuard] }, { path: '**', component: Login }, ]; 

Je voudrais faire un pas plus loin et indiquer également quel rôle d'utilisateur ont «accès» à l'itinéraire – mais je ne sais pas comment passer l'argument à canActivate AuthGuard (src) . Je voudrais donc réaliser quelque chose comme ça (par exemple, j'ai deux rôles: Administrateur et Employé):

  { path: 'home', component: Home, canActivate: [AuthGuard] }, { path: 'users', component: AdminUsers, canActivate: [AuthGuard('Admin')] }, { path: 'users', component: Employees, canActivate: [AuthGuard('Employee')] }, 

Où mon AuthGuard pourrait ressembler à quelque chose comme ça (où UserRole (= Admin ou Employé ou null) est passé au paramètre AuthGuard):

 @Injectable() export class AuthGuard implements CanActivate { constructor(private router: Router) {} canActivate(userRole) { if (!userRole || JWT.user().role == userRole) { return true; } this.router.navigate(['/login']); return false; } } 

Où JWT.user.role est un assistant qui lit le rôle utilisateur stocké dans le jeton JWT. Existe-t-il un moyen de faire quelque chose de similaire à celui de l'idée ci-dessus?

La signature de CanActivate ne vous permettra pas de passer un userRole comme vous le souhaitez. https://github.com/angular/angular/blob/2.0.0-rc.4/modules/%40angular/router/src/interfaces.ts#L54

Il est probablement préférable de faire des cours distincts pour chacun de vos cas de rôle utilisateur. C'est aussi l'orientation dans les documents officiels: https://angular.io/docs/ts/latest/api/router/index/CanActivate-interface.html

Vous pouvez définir le paramètre de data de l'itinéraire avec le rôle comme celui-ci

 const appRoutes: Routes = [ { path: 'account/super-secure', component: SuperSecureComponent, canActivate: [RoleGuard], data: { roles: ['super-admin', 'admin'] } }]; 

REMARQUE : applicable pour angular-rc.4 <

@ KamilKiełczewski, @NikolayRusev,

  1. Ajout de données supplémentaires sur l'itinéraire avec un ensemble d'itinéraires:

 ... { path: "customers", component: CustomersCmp, data: { roles: ["admin"] } }, ... 

Et dans CanActivate, vous pouvez obtenir le path du premier paramètre, rechercher le même chemin dans la configuration de l'itinéraire et obtenir les rôles décrits à partir des données:

 public canActivate(route: ActivatedRouteSnapshot): boolean { let path = route._urlSegment.pathsWithParams[0].path; let roles; if (route._routeConfig.path == path) { roles = route._routeConfig.data.roles } else { roles = route._routeConfig.children.find(_route => _route.path == path).data.roles; } if (...) { return true; } return false; } 

Bien sûr, il serait préférable d'éviter les propriétés privées, et vous pouvez, mais je ne me souviens pas comment je l'ai exactement fait.

Mais, pour mes besoins, je le redis de manière différente. L'inconvénient énorme de cette approche, je veux dire pour la protection basée sur les rôles, est que chaque utilisateur avec différents rôles peut voir toutes les routes si vous les rendez automatiquement dans un composant.

  1. Vous pouvez étendre le router-outlet