Difference between Angular's canLoad and canActivate?

Angular

Angular Problem Overview


What is the difference between canLoad and 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;
}

When I should which one of them?

Angular Solutions


Solution 1 - Angular

canActivate is used to prevent unauthorized users from accessing certain routes. See docs for more info.

canLoad is used to prevent the application from loading entire modules lazily if the user is not authorized to do so.

See docs and example below for more info.

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

With this code, the code for the AdminModule will only be loaded into the application if AuthGuard returns true.

If the user is not authorized to access this route, and we'd only used a canActivate guard, the AdminModule would be loaded, even though the user would not be able to access that route.

Solution 2 - Angular

  • CanActivate - Decides if a route can be activated, this guard may not be the best way for feature modules that are lazy loaded, as this guard will always load the module in memory, even if the guard returned false which means user not authorized to access the route.
  • CanLoad - Decides if a module can be loaded lazily, Controls if a route can even be loaded. This becomes useful for feature modules that are lazy loaded. They won’t even load if the guard returns false.

This is a test i made on both guards with a feature module that is lazy loaded:

1. CanActivate Guard Test

you will notice at the bottom of Network page that it made 24 requests with size of 9.5 MB transferred finishing in 3.34 seconds and fully loaded in 3.47 seconds.

CanActivate Guard Test On Lazy Loaded Feature Module

1. CanLoad Guard Test

here you will see the big difference when we used CanLoad Guard as browser made only 18 requests with size of 9.2 MB transferred finishing in 2.64 seconds and fully loaded 2.59 seconds.

CanLoad Guard Test On Lazy Loaded Feature Module

CanLoad Guard never load the module data if user not authorized and that gives you more performance as the load time decreased almost 1 second and that is huge time in loading web pages, no doubt it depends on the module size.

> Tip: if you want to make the test on your project make sure that Disable Cache checkbox in network tab is checked, it's marked in first image

Solution 3 - Angular

The CanLoad Guard prevents the loading of the Lazy Loaded Module. We generally use this guard when we do not want to unauthorized user to navigate to any of the routes of the module and also stop then even see the source code of the module.

The Angular provides canActivate Guard, which prevents unauthorized user from accessing the route. But it does not stop the module from being downloaded. The user can use the chrome developer console to see the source code. The CanLoad Guard prevents the module from being downloaded.

Actually,CanLoad protects a module to be loaded but once module is loaded then CanLoad guard will do nothing. Suppose we have protected a module loading using CanLoad guard for unauthenticated user. When user is logged-in then that module will be applicable to be loaded and we will be able to navigate children paths configured by that module. But when user is logged-out, still user will be able to navigate those children paths because module is already loaded. In this case if we want to protect children paths from unauthorized users, we also need to use CanActivate guard.

Use CanLoad before loading AdminModule:

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

After loading AdminModule, in AdminRouting module we can use CanActivate to protect childs from unauthorized users like bellow:

{ 
	  path: '',
	  component: AdminComponent,
	  children: [ 
	    {
	      path: 'person-list',
	      component: PersonListComponent,
	      canActivate: [ AuthGuardService ]
	    }
	  ]
	}  

Solution 4 - Angular

Regarding to question from comments in other post "If I use canActivate in above scenario, what will be the difference ?"

Actually for user there will be no difference, he won't get any access to the page in both cases. Although there is one hidden difference. If you press F12 and move to Sources (in Chrome) where are download files. Then you can see that in case with canActive file with code has been downloaded (chunk.js). Even if you have no access to the page. enter image description here

But in case with canLoad there will be no chunk.js file with source code.

enter image description here

So as you can see this have really big impact for security.

And of course don't forget that canLoad can be used only for LazyLoaded Modules.

Solution 5 - Angular

canActivate is used to prevent an unauthorized user

canLoad is used to prevent the entire module of app

Example of canActivate:

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

Example of canLoad:

{ path: 'user' , canLoad: [AuthenticGuard], loadChildren : './user/user.module#UserModule' }

Solution 6 - Angular

Important to notice that canLoad won't stop someone from getting your source code. The .js won't be downloaded by browser unless user is authorized, but you can force a manual download by issuing a import('./xxxxx.js') on browser console.

Module name can be easly found on you main.js on your routes definition.

Solution 7 - Angular

Following are the cases that I have found while using canLoad and canActivete with lazy routes:

A) If canLoad or canActivate is used:

1. When module is not downloaded already:

canLoad: 
  true: module will be downloaded
  false: module will not be downloaded

canActivate:
  true: module will be downloaded and user will be granted to access particular route
  false: module will be downloaded and user will be prevented to access particular route

2. When module is downloaded already

canLoad: It does not do anything. Like its not there in code.

canActivate:
  true: user will be granted to access particular route
  false: user will be prevented to access particular route

B) If both canLoad and canActivate is used:

1. When module is not downloaded already:

canLoad: 
  true: module will be downloaded and passed control to check canActivate
  false: Neither module will be downloaded nor canActivate will be called

canActivate:
  true: user will be granted to access particular route
  false: user will be prevented to access particular route

2. When module is downloaded already

canLoad:
  It does not do anything. Like its not there.

canActivate:
  true: user will be granted to access particular route
  false: user will be prevented to access particular route

So I prefer using both canLoad and canActivate for lazy modules and canActivate for component based route

Solution 8 - Angular

A big difference no one mentioned here, is that canLoad only works with loadChildren.

To prevent a component from being loaded, only canActivate will get triggered.

See https://stackoverflow.com/q/40011143/9450152 for more detail.

Solution 9 - Angular

canActivate if unauthorized user enters still load that module . you need canLoad to achieve judgment whether it needs be loaded .

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYoav SchniedermanView Question on Stackoverflow
Solution 1 - AngularFredrik LundinView Answer on Stackoverflow
Solution 2 - AngularMahmoud FawzyView Answer on Stackoverflow
Solution 3 - AngularMohammad NiazmandView Answer on Stackoverflow
Solution 4 - AngularDiPixView Answer on Stackoverflow
Solution 5 - AngularSagar JadhavView Answer on Stackoverflow
Solution 6 - AngularIvan MuricyView Answer on Stackoverflow
Solution 7 - AngularnavnathView Answer on Stackoverflow
Solution 8 - AngularkotchwaneView Answer on Stackoverflow
Solution 9 - AngularLiHaoView Answer on Stackoverflow