ng-secure-access
v2.1.1
Published
Librairie Angular pour la gestion des permissions d'accès aux routes et l'affichage conditionnel basé sur les permissions utilisateur
Maintainers
Readme
ng-secure-access
ng-secure-access est une librairie Angular qui permet de gérer les permissions d'accès aux routes et l'affichage des éléments en fonction des permissions d'un utilisateur. Elle permet de charger dynamiquement les permissions après l'authentification et de contrôler l'accès aux différentes parties de votre application.
📋 Fonctionnalités
- ✅ Gestion des permissions dynamiques : Charge un tableau de permissions pour un utilisateur après l'authentification
- ✅ Protection des routes : Utilise un
Guardpour vérifier les permissions avant d'accéder à une route - ✅ Affichage conditionnel des éléments : Affiche ou masque des éléments en fonction des permissions
- ✅ Redirection dynamique : Redirige l'utilisateur vers des pages spécifiques s'il n'a pas les permissions requises
- ✅ Signals Angular : Utilise les signals pour une réactivité optimale
- ✅ Standalone : Compatible avec l'approche moderne d'Angular
- ✅ TypeScript : Entièrement typé
🚀 Installation
npm install ng-secure-access📖 Utilisation
1. Charger les permissions
Les permissions doivent être chargées après l'authentification de l'utilisateur, par exemple dans un LayoutComponent :
import { Component, OnInit } from '@angular/core';
import { PermissionService } from 'ng-secure-access';
@Component({
selector: 'app-layout',
templateUrl: './layout.component.html',
})
export class LayoutComponent implements OnInit {
constructor(private permissionService: PermissionService) {}
ngOnInit() {
// Charger les permissions après l'authentification de l'utilisateur
this.permissionService.loadPermissions(['update', 'delete', 'create']);
}
}Exemple avec une API
import { Component, OnInit } from '@angular/core';
import { PermissionService } from 'ng-secure-access';
import { AuthService } from './services/auth.service';
@Component({
selector: 'app-layout',
templateUrl: './layout.component.html',
})
export class LayoutComponent implements OnInit {
constructor(
private permissionService: PermissionService,
private authService: AuthService
) {}
ngOnInit() {
// Charger les permissions depuis l'API
this.authService.getUserPermissions().subscribe(permissions => {
this.permissionService.loadPermissions(permissions);
});
}
}2. Protéger une route avec des permissions
Pour protéger une route, ajoutez le PermissionGuard à votre route et spécifiez les permissions requises dans data.
import { Routes } from '@angular/router';
import { PermissionGuard } from 'ng-secure-access';
const routes: Routes = [
{
path: 'create',
canActivate: [PermissionGuard],
data: {
permissions: ['create'], // L'utilisateur doit avoir AU MOINS une de ces permissions
redirectTo: '/access-denied' // Redirection en cas de permissions insuffisantes
},
loadComponent: () => import('./pages/create-page/create-page.component').then(m => m.CreatePageComponent),
},
{
path: 'dashboard',
canActivate: [PermissionGuard],
data: {
permissions: ['viewDashboard', 'admin'], // Au moins une de ces permissions
redirectTo: '/no-access'
},
loadComponent: () => import('./pages/dashboard/dashboard.component').then(m => m.DashboardComponent),
}
];3. Afficher des éléments conditionnellement
Utilisez la directive *hasPermission pour afficher ou masquer des éléments en fonction des permissions d'un utilisateur.
import { Component } from '@angular/core';
import { HasPermissionDirective } from 'ng-secure-access';
@Component({
selector: 'app-menu',
standalone: true,
imports: [HasPermissionDirective],
template: `
<!-- Afficher si l'utilisateur a AU MOINS une des permissions -->
<button *hasPermission="['update', 'delete']">
Actions
</button>
<div *hasPermission="['admin']">
Panneau d'administration
</div>
<a routerLink="/dashboard" *hasPermission="['viewDashboard']">
Dashboard
</a>
`
})
export class MenuComponent {}4. Gérer les permissions dynamiquement
import { Component } from '@angular/core';
import { PermissionService } from 'ng-secure-access';
@Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
})
export class UserProfileComponent {
constructor(private permissionService: PermissionService) {}
// Vérifier une permission spécifique
canEdit(): boolean {
return this.permissionService.hasSpecificPermission('edit');
}
// Obtenir toutes les permissions
getUserPermissions(): string[] {
return this.permissionService.getPermissions();
}
// Ajouter une permission temporaire
grantTemporaryAccess(): void {
this.permissionService.addPermission('temporary-access');
}
// Se déconnecter et effacer les permissions
logout(): void {
this.permissionService.clearPermissions();
// Rediriger vers la page de connexion...
}
}📦 API
PermissionService
| Méthode | Description |
|---------|-------------|
| loadPermissions(permissions: string[]): void | Charge les permissions pour l'utilisateur actuel |
| hasPermission(permissions: string[]): boolean | Vérifie si l'utilisateur possède au moins une des permissions spécifiées (logique OU) |
| hasSpecificPermission(permission: string): boolean | Vérifie si l'utilisateur possède une permission spécifique |
| getPermissions(): string[] | Retourne toutes les permissions de l'utilisateur |
| arePermissionsLoaded(): boolean | Retourne true si les permissions sont chargées |
| clearPermissions(): void | Efface toutes les permissions (utile lors de la déconnexion) |
| addPermission(permission: string): void | Ajoute une permission dynamiquement |
| removePermission(permission: string): void | Retire une permission |
HasPermissionDirective
Sélecteur : *hasPermission
Input : string[] - Liste des permissions (logique OU : au moins une permission requise)
<button *hasPermission="['update', 'delete', 'admin']">
Actions disponibles
</button>PermissionGuard
Utilisation : canActivate: [PermissionGuard]
Configuration de la route :
{
path: 'protected',
canActivate: [PermissionGuard],
data: {
permissions: string[], // Permissions requises (au moins une)
redirectTo: string // URL de redirection (optionnel, défaut: '/access-denied')
}
}📝 Exemples complets
Menu de navigation avec permissions
import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { HasPermissionDirective } from 'ng-secure-access';
@Component({
selector: 'app-navbar',
standalone: true,
imports: [RouterLink, HasPermissionDirective],
template: `
<nav>
<a routerLink="/home">Accueil</a>
<a routerLink="/dashboard" *hasPermission="['viewDashboard']">
Dashboard
</a>
<a routerLink="/users" *hasPermission="['manageUsers', 'admin']">
Utilisateurs
</a>
<a routerLink="/settings" *hasPermission="['admin']">
Paramètres
</a>
<a routerLink="/reports" *hasPermission="['viewReports']">
Rapports
</a>
</nav>
`
})
export class NavbarComponent {}Boutons d'action conditionnels
<div class="card">
<h3>Article</h3>
<p>Contenu de l'article...</p>
<div class="actions">
<button *hasPermission="['read']" (click)="view()">
Voir
</button>
<button *hasPermission="['update', 'admin']" (click)="edit()">
Modifier
</button>
<button *hasPermission="['delete', 'admin']" (click)="delete()">
Supprimer
</button>
</div>
</div>Configuration complète des routes
import { Routes } from '@angular/router';
import { PermissionGuard } from 'ng-secure-access';
export const routes: Routes = [
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
},
{
path: 'home',
loadComponent: () => import('./pages/home/home.component').then(m => m.HomeComponent)
},
{
path: 'dashboard',
canActivate: [PermissionGuard],
data: {
permissions: ['viewDashboard'],
redirectTo: '/access-denied'
},
loadComponent: () => import('./pages/dashboard/dashboard.component').then(m => m.DashboardComponent)
},
{
path: 'users',
canActivate: [PermissionGuard],
data: {
permissions: ['manageUsers', 'admin'],
redirectTo: '/access-denied'
},
loadComponent: () => import('./pages/users/users.component').then(m => m.UsersComponent)
},
{
path: 'access-denied',
loadComponent: () => import('./pages/access-denied/access-denied.component').then(m => m.AccessDeniedComponent)
}
];🔒 Sécurité
⚠️ Important : Cette librairie gère uniquement l'affichage et la navigation côté client.
Vous devez toujours valider les permissions côté serveur !
Les permissions frontend servent à :
- ✅ Améliorer l'expérience utilisateur en cachant les options inaccessibles
- ✅ Éviter les requêtes inutiles vers le backend
- ✅ Guider l'utilisateur dans l'interface
Elles ne remplacent PAS la sécurité backend. Toutes les actions sensibles doivent être validées par votre API.
📋 Prérequis
- Angular 17+ (pour la syntaxe standalone et les signals)
- TypeScript 5.x+
- RxJS 7.x+
🤝 Contribution
Les contributions sont les bienvenues ! Si vous souhaitez améliorer cette librairie ou signaler un problème, merci de :
- Ouvrir une issue pour discuter des changements
- Soumettre une pull request avec vos améliorations
📄 Licence
MIT © BIBANG BEFENE Joseph Donovan
🔗 Liens utiles
✨ Auteur
Créé avec ❤️ par BIBANG BEFENE Joseph Donovan
Note : Si vous rencontrez des problèmes ou avez des questions, n'hésitez pas à ouvrir une issue sur GitHub.
