Le routage Angular2 peut activer et AuthGuard (JWT) avec le paramètre rôle de l'utilisateur
Dans ce projet exaple avec l'authentification JWT nous voyons comment autoriser seulement les utilisateurs authentifiés à certaines routes:
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 de plus et aussi indiquer quel rôle de l'Utilisateur a 'accès' à route-mais je ne sais pas comment passer l'argument pour 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')] },
où mon AuthGuard pourrait regarder 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.utilisateur.le rôle est l'assistant qui lit le rôle de l'utilisateur stocké dans le JWT token. Est-il un moyen de faire quelque chose de similaire, comme au-dessus de l'idée?
3 réponses
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 classes séparées pour chacun de vos cas de rôle d'utilisateur. C'est aussi ce que disent les documents officiels: https://angular.io/docs/ts/latest/api/router/index/CanActivate-interface.html
vous pouvez définir le
const appRoutes: Routes = [
{
path: 'account/super-secure',
component: SuperSecureComponent,
canActivate: [RoleGuard],
data: { roles: ['super-admin', 'admin'] }
}];
et puis c'est en canActivate
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 le faire au lieu de créer une garde pour chaque rôle. Je voudrais en fait prendre cette déroute car il nécessite moins de code et gère le problème très bien.
NOTE: applicable pour les angulaires-rc.4<
@KamilKiełczewski, @NikolayRusev,
ajouté en route données supplémentaires avec tableau des routes:
...
{
path: "customers",
component: CustomersCmp,
data: { roles: ["admin"] }
},
...
et dans CanActivate vous pouvez obtenir path
à partir du premier paramètre, cherchez le même chemin dans la config route et obtenez vos 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 des propriétés privées, et vous pouvez, mais je ne me souviens pas comment je l'ai fait.
mais pour mes porposes Je l'ai redirigé de manière différente. Le grand inconvénient de cette approche, je veux dire pour la garde basée sur les rôles, est que chaque utilisateur avec des rôles différents peut voir toutes les routes si vous les rendez dans un composant automatiquement pas manuellement.