43 votes

Routage angulaire2 canActivate et AuthGuard (JWT) avec paramètre de rôle d'utilisateur

Dans ce exaple projet avec JWT l'authentification de nous se comment autoriser uniquement les utilisateurs authentifiés à certains itinéraire:

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 plus loin et d'indiquer également ce rôle d'utilisateur d'avoir l'accès à la voie - mais je ne sais pas comment passer en argument à canActivate AuthGuard (src). Donc je voudrais obtenir quelque chose comme ceci (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')] },

D'où mon AuthGuard pourrait ressembler à quelque chose comme ceci (où userRole(= Administrateur ou d'un Employé ou nulle) est passé en 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.de l'utilisateur.le rôle est helper qui lire du rôle de l'utilisateur stockées dans JWT jeton. Est-il un moyen de faire quelque chose de similaire, comme au-dessus de l'idée?

85voto

Arman Points 770

Vous pouvez définir l' data paramètre de la route avec le rôle comme ceci

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

et puis c'est en canActivate de RoleGuard:

canActivate(route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): boolean {

    let roles = route.data["roles"] as Array<string>;
    return (roles == null || roles.indexOf("the-logged-user-role") != -1);
}

Je pense que cela pourrait être une autre façon de faire au lieu de créer de la garde pour chaque rôle. En fait, je peux profiter de cette déroute, car il nécessite moins de code et gère le problème très bien.

6voto

cienki Points 706

La signature d' 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 sans doute préférable de faire des classes séparées pour chaque rôle d'utilisateur des cas. C'est le guide officiel de l'docs trop: https://angular.io/docs/ts/latest/api/router/index/CanActivate-interface.html

2voto

Andrei Shostik Points 162

REMARQUE: applicable pour angulaires-rc.4 <

@KamilKiełczewski, @NikolayRusev,

  1. ajouté à l'itinéraire des données supplémentaires avec le tableau de routes:

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

et dans CanActivate vous pouvez obtenir de l' path à partir du premier paramètre, recherche le même chemin en route config et obtenir votre décrit les rôles à 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 des propriétés privées, et vous pouvez, mais je ne me souviens pas comment j'ai exactement fait.

Mais pour ma porposes j'ai refait une manière différente. Le grand désavantage de cette approche, je veux dire pour l'basées sur le rôle de la garde, est que chaque utilisateur avec différents rôles peuvent voir l'ensemble de l'itinéraire de vous rendre dans un composant automatiquement pas manuellement.

  1. vous pouvez étendre router-outlet

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X