Différence entre canLoad et canActivate d'Angular?

100

Quelle est la différence entre canLoadet canActivate?

export interface Route {
  path?: string;
  pathMatch?: string;
  matcher?: UrlMatcher;
  component?: Type<any>;
  redirectTo?: string;
  outlet?: string;
  canActivate?: any[];
  canActivateChild?: any[];
  canDeactivate?: any[];
  canLoad?: any[];
  data?: Data;
  resolve?: ResolveData;
  children?: Routes;
  loadChildren?: LoadChildren;
}

Quand devrais-je lequel d'entre eux?

Yoav Schniederman
la source

Réponses:

99

canActivate est utilisé pour empêcher les utilisateurs non autorisés d'accéder à certaines routes. Consultez la documentation pour plus d'informations.

canLoad est utilisé pour empêcher l'application de charger paresseusement des modules entiers si l'utilisateur n'est pas autorisé à le faire.

Voir la documentation et l'exemple ci-dessous pour plus d'informations.

{
    path: 'admin',
    loadChildren: 'app/admin/admin.module#AdminModule',
    canLoad: [AuthGuard]
},

Avec ce code, le code de l'AdminModule ne sera chargé dans l'application que si AuthGuard revient true.

Si l'utilisateur n'est pas autorisé à accéder à cette route et que nous n'avons utilisé qu'un canActivategarde, le AdminModuleserait chargé, même si l'utilisateur ne pourrait pas accéder à cette route.

Fredrik Lundin
la source
6
Si j'utilise canActivatedans le scénario ci-dessus, quelle sera la différence?
k11k2
3
@ k11k2 avec le canActivemodule sera chargé (F12> Sources - dans chrome). Vous pouvez voir les fichiers .js ici. Avec canLoadces modules (fichiers .js) ne seront pas chargés :) Vérifiez ma réponse ci-dessus où je l'ai mieux expliqué
DiPix
23
Qu'en est-il du scénario où l'administrateur s'est connecté, de sorte que le module d'administration a été chargé via canLoadrenvoie true, puis se déconnecte de l'application. Maintenant, un utilisateur non-administrateur se connecte dans le même navigateur, comment ça marche? Le module chargé a-t-il été expulsé ou supprimé du cache?
Keerthivasan
2
@Keerthivasan rien n'oblige à supprimer le morceau précédemment chargé du module d'administration paresseux lorsqu'un utilisateur se déconnecte et se reconnecte avec un compte différent qui n'a pas assez d'autorisations pour charger AdminModule. Cependant, vous n'obtiendrez pas l'accès de toute façon .. sauf d'avoir un module mis en cache chargé. Je ne pense pas que ce soit un vrai problème de sécurité car généralement un appareil est un utilisateur réel
hastrb
1
@ sgClaudia98 vous pouvez utiliser les deux, mais il y a un ordre strict d'exécution des gardes. c'est pourquoi cela ne fait aucune différence dans votre cas par rapport à ce que j'ai dit un peu plus tôt. Je pense avoir mis des explications très détaillées dans mon premier commentaire. Ce serait un cas assez étrange s'il y avait un appareil et une connexion administrateur / non administrateur un par un de nos jours.
hastrb
36
  • CanActivate - Décide si une route peut être activée, cette garde peut ne pas être le meilleur moyen pour les modules de fonctionnalités qui sont chargés paresseusement, car cette garde chargera toujours le module en mémoire, même si la garde a renvoyé false, ce qui signifie que l'utilisateur n'est pas autorisé à accéder la route.
  • CanLoad - Décide si un module peut être chargé paresseusement, Contrôle si une route peut même être chargée. Cela devient utile pour les modules de fonctionnalités qui sont chargés tardivement. Ils ne se chargeront même pas si le garde renvoie false.

Ceci est un test que j'ai fait sur les deux gardes avec un module de fonctionnalités qui est chargé paresseusement:

1. Test de protection CanActivate

vous remarquerez en bas de la page Réseau qu'il a effectué 24 requêtes d'une taille de 9,5 Mo transférées en 3,34 secondes et entièrement chargées en 3,47 secondes.

CanActivate Guard Test sur le module de fonctions à chargement différé

1. Test de CanLoad Guard

ici, vous verrez la grande différence lorsque nous avons utilisé CanLoad Guard car le navigateur n'a fait que 18 requêtes avec une taille de 9,2 Mo transférées, finissant en 2,64 secondes et 2,59 secondes à pleine charge.

Test CanLoad Guard sur le module de fonctions à chargement différé

CanLoad Guard ne charge jamais les données du module si l'utilisateur n'est pas autorisé et cela vous donne plus de performances car le temps de chargement a diminué de presque 1 seconde et c'est un temps énorme pour charger les pages Web, cela dépend sans aucun doute de la taille du module.

Astuce: si vous souhaitez faire le test sur votre projet, assurez-vous que la Disable Cachecase à cocher dans l'onglet réseau est cochée, elle est marquée dans la première image

Mahmoud Fawzy
la source
3
Juste pour ne pas confondre quelqu'un .. 403 est Forbbiden, pas non autorisé qui est 401.
hastrb
20

En ce qui concerne la question des commentaires dans un autre message "Si j'utilise canActivate dans le scénario ci-dessus, quelle sera la différence?"

En fait, pour l'utilisateur, il n'y aura aucune différence, il n'aura aucun accès à la page dans les deux cas. Bien qu'il y ait une différence cachée . Si vous appuyez sur F12 et passez à Sources (dans Chrome) où se trouvent les fichiers téléchargés. Ensuite, vous pouvez voir que dans le cas où le fichier canActive avec le code a été téléchargé ( chunk.js ). Même si vous n'avez pas accès à la page. entrez la description de l'image ici

Mais dans le cas de canLoad, il n'y aura pas de fichier chunk.js avec le code source.

entrez la description de l'image ici

Comme vous pouvez le voir, cela a un impact très important sur la sécurité.

Et bien sûr, n'oubliez pas que canLoad ne peut être utilisé que pour les modules LazyLoaded .

DiPix
la source
3
impossible de voir des morceaux pour le module de chargement paresseux dans mon onglet réseau mais les itinéraires fonctionnent comme prévu, comment puis-je confirmer le chargement de mes modules à la demande ou non?
k11k2
@ k11k2 si vous voulez voir de quel fichier un module fait partie, ajoutez simplement une debugger;instruction dans le constructeur pour l'un des composants de ce module. Vous pouvez alors voir s'il a été chargé comme un morceau séparé ou inclus dans un module tel que main. Si vous avez des références à des composants dans un module différé qui ne sont pas isolés de ce module, il peut être chargé de toute façon. Si vous voyez cela, cela suggère soit que vous filtrez par autre chose que des fichiers JS, soit que vous devez séparer votre module paresseux en parties communes et «vraiment paresseuses».
Simon_Weaver
@ k11k2 Je pense que votre "module de chargement paresseux" n'est pas chargé paresseusement. Assurez-vous que vous avez utilisé la loadChildrenpropriété dans le cadre du chemin d'accès à votre module différé.
hastrb
16

canActivate est utilisé pour empêcher un utilisateur non autorisé

canLoad est utilisé pour empêcher tout le module de l'application

Exemple de canActivate :

{ path: 'product',canActivate:[RouteGaurd], component : ProductComponent }

Exemple de canLoad :

{ path: 'user' , canLoad: [AuthenticGuard], loadChildren : './user/user.module#UserModule' }
Sagar Jadhav
la source
Pour les futurs lecteurs, l'exemple canActive n'est pas paresseux, mais canLoad est .. dû à avoir loadChildren. De plus, une version récente de angular est ..loadChildren: () => import('./user/user.module').then(m => m.UserModule)
hastrb
Explication très simple, j'ai aimé :)
KTM
16

La canLoad Guard empêche le chargement du module Loaded Lazy. Nous utilisons généralement cette garde lorsque nous ne voulons pas à un utilisateur non autorisé de naviguer vers l'une des routes du module et également de s'arrêter puis même de voir le code source du module.

L'Angular fournit canActivate Guard, qui empêche les utilisateurs non autorisés d'accéder à l'itinéraire. Mais cela n'empêche pas le téléchargement du module. L'utilisateur peut utiliser la console de développement Chrome pour voir le code source. CanLoad Guard empêche le téléchargement du module.

En fait, CanLoad protège un module à charger, mais une fois le module chargé, CanLoad guard ne fera rien. Supposons que nous ayons protégé un chargement de module à l'aide de CanLoad guard pour un utilisateur non authentifié. Lorsque l'utilisateur est connecté, ce module sera applicable pour être chargé et nous pourrons naviguer dans les chemins enfants configurés par ce module. Mais lorsque l'utilisateur est déconnecté, l'utilisateur pourra toujours naviguer dans ces chemins enfants car le module est déjà chargé. Dans ce cas, si nous voulons protéger les chemins enfants des utilisateurs non autorisés, nous devons également utiliser la garde CanActivate .

Utilisez CanLoad avant de charger AdminModule:

  {
        path: 'admin',
        loadChildren: 'app/admin/admin.module#AdminModule',
        canLoad: [ AuthGuardService ]
      },

Après avoir chargé AdminModule, dans le module AdminRouting, nous pouvons utiliser CanActive pour protéger les enfants contre les utilisateurs non autorisés comme ci-dessous:

{ 
      path: '',
      component: AdminComponent,
      children: [ 
        {
          path: 'person-list',
          component: PersonListComponent,
          canActivate: [ AuthGuardService ]
        }
      ]
    }  
Mohammad Niazmand
la source
On devrait donc utiliser à la fois canLoad et canActivate?
Tarida George
0

canActivate si un utilisateur non autorisé entre toujours charger ce module. vous avez besoin de canLoad pour déterminer s'il doit être chargé.

LiHao
la source
0

Il est important de noter que canLoad n'empêchera personne d'obtenir votre code source. Le .js ne sera pas téléchargé par le navigateur à moins que l'utilisateur n'y soit autorisé, mais vous pouvez forcer un téléchargement manuel en exécutant une importation ('./ xxxxx.js') sur la console du navigateur.

Le nom du module peut être facilement trouvé sur votre main.js sur la définition de vos itinéraires.

Ivan Muricy
la source