Angular的canLoad和canActivate之间的区别?

Yoa*_*man 62 angular

canLoad和之间有什么区别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;
}
Run Code Online (Sandbox Code Playgroud)

什么时候我应该选哪一个?

Fre*_*din 69

canActivate用于防止未经授权的用户访问某些路由.有关详细信息,请参阅文档.

如果用户没有被授权,则canLoad用于防止应用程序懒惰地加载整个模块.

有关详细信息,请参阅下面的文档和示例.

{
    path: 'admin',
    loadChildren: 'app/admin/admin.module#AdminModule',
    canLoad: [AuthGuard]
},
Run Code Online (Sandbox Code Playgroud)

使用此代码,只有AuthGuard返回时,AdminModule的代码才会加载到应用程序中true.

如果用户未被授权访问此路由,并且我们仅使用了canActivate防护,AdminModule则将加载,即使用户将无法访问该路由.

  • 管理员登录的情况怎么样,所以管理模块通过`canLoad`加载后返回true,然后退出应用程序.现在,非管理员用户在同一浏览器中登录,它是如何工作的?加载的模块是否已从缓存中逐出或删除? (17认同)
  • 如果我在上面的场景中使用`canActivate`,会有什么区别? (5认同)
  • 带有 `canActive` 模块的 @k11k2 将被加载(F12 &gt; Sources - 在 chrome 中)。你可以在那里看到 .js 文件。使用 `canLoad` 这些模块(文件 .js)不会被加载:) 检查我上面的答案,我解释得更好 (3认同)
  • @Keerthivasan,当用户注销并使用其他没有足够权限加载 AdminModule 的帐户再次登录时,没有任何强制措施删除先前加载的惰性 AdminModule 块。但是,无论如何您都无法获得访问权限......除非加载了缓存模块。我不认为这是一个真正的安全问题,因为通常一台设备是一个真实用户 (3认同)
  • @sgClaudia98,您可以同时使用两者,但是守卫的执行顺序有严格的要求。这就是为什么我之前所说的对你的情况没有什么影响。我想我在第一条评论中做了非常详细的解释。如果现在只有一台设备并且管理员/非管理员一一登录,那将是非常奇怪的情况。 (2认同)
  • 注意:canActivate 在每次路由更改时触发,但 canLoad 仅在第一次加载模块时触发。如果您的逻辑需要在每次访问路线时运行,则必须使用 canActivate (或将逻辑移至其他位置)。canActivate 和 canLoad 可以一起使用。 (2认同)

Moh*_*and 29

所述CanLoad保护防止延迟加载模块的加载。当我们不希望未经授权的用户导航到模块的任何路由,也不想停下来甚至查看模块的源代码时,我们通常会使用此防护。

Angular 提供了canActivate Guard,可以防止未经授权的用户访问路由。但它不会阻止模块被下载。用户可以使用chrome开发者控制台查看源代码。CanLoad Guard 防止模块被下载。

实际上,CanLoad保护要加载的模块,但是一旦加载了模块,CanLoad防护就什么也不做。假设我们已经使用CanLoad防护为未经身份验证的用户保护了一个模块加载。当用户登录时,该模块将适用于加载,我们将能够导航由该模块配置的子路径。但是当用户注销时,用户仍然可以导航这些子路径,因为模块已经加载。在这种情况下,如果我们想保护子路径免受未经授权的用户的攻击,我们还需要使用CanActivate防护。

在加载 AdminModule 之前使用CanLoad

  {
        path: 'admin',
        loadChildren: 'app/admin/admin.module#AdminModule',
        canLoad: [ AuthGuardService ]
      },
Run Code Online (Sandbox Code Playgroud)

加载 AdminModule 后,在 AdminRouting 模块中,我们可以使用CanActivate来保护孩子免受未经授权的用户的侵害,如下所示:

{ 
      path: '',
      component: AdminComponent,
      children: [ 
        {
          path: 'person-list',
          component: PersonListComponent,
          canActivate: [ AuthGuardService ]
        }
      ]
    }  
Run Code Online (Sandbox Code Playgroud)

  • 注意:CanActivate 在每次路由更改时触发,但 canLoad 仅在第一次加载模块时触发。如果您的逻辑需要在每次访问路线时运行,则必须使用 canActivate (或将逻辑移至其他位置)。canActivate 和 canLoad 可以一起使用。 (3认同)

Mah*_*wzy 21

  • CanActivate-决定是否可以激活路由,此防护可能不是延迟加载的功能模块的最佳方法,因为此防护将始终将模块加载到内存中,即使该防护返回false,这也意味着用户无权访问路线。
  • CanLoad-决定是否可以延迟加载模块,控制是否可以加载路由。这对于延迟加载的功能模块很有用。如果警卫队返回假,他们甚至不会加载。

这是我对两个后卫使用延迟加载的功能模块进行的测试:

1.可以激活Guard测试

您会在“网络”页面的底部注意到,它发出了24个9.5 MB大小的请求,这些请求在3.34秒内完成传输,并在3.47秒内完成加载。

可以在延迟加载的功能模块上激活Guard测试

1. CanLoad Guard测试

在这里,当我们使用CanLoad Guard时,您会看到很大的不同,因为浏览器仅发出了9.2 MB大小的18个请求,在2.64秒内完成传输,并在2.59秒内完成满载。

在延迟加载的功能模块上进行CanLoad Guard测试

如果用户未授权,CanLoad Guard永远不会加载模块数据,这将为您带来更高的性能,因为加载时间减少了将近1秒钟,并且这是加载网页的巨大时间,毫无疑问,这取决于模块的大小。

提示: 如果要在项目上进行测试,请确保Disable Cache选中“网络”选项卡中的复选框,该复选框已在第一个图像中标记

  • 只是为了不混淆某人.. 403 是 Forbbiden,而不是 401 未经授权。 (5认同)

DiP*_*Pix 16

关于来自其他帖子中的评论的问题 "如果我在上面的场景中使用canActivate,会有什么区别?"

实际上对于用户而言没有区别,在这两种情况下他都不会获得对页面的任何访问权限.虽然有一个隐藏的区别.如果您按F12并移至源(在Chrome中)下载文件.然后你可以看到,如果已经下载了带有代码的canActive文件(chunk.js).即使您无法访问该页面. 在此输入图像描述

但是对于canLoad,将没有带源代码的chunk.js文件.

在此输入图像描述

因此,您可以看到这对安全性有很大影响.

当然不要忘记canLoad只能用于LazyLoaded 模块.

  • 无法在我的网络选项卡中看到延迟加载模块的任何块,但路由按预期工作,如何确认我的模块是否按需加载? (2认同)

小智 10

canActivate用于防止未经授权的用户

canLoad用于阻止应用程序的整个模块

canActivate的示例:

{ path: 'product',canActivate:[RouteGaurd], component : ProductComponent }
Run Code Online (Sandbox Code Playgroud)

canLoad示例:

{ path: 'user' , canLoad: [AuthenticGuard], loadChildren : './user/user.module#UserModule' }
Run Code Online (Sandbox Code Playgroud)

  • 对于未来的读者来说,canActive 示例并不懒惰,但 canLoad 是..由于有“loadChildren”。此外,最新版本的 Angular 是.. `loadChildren: () =&gt; import('./user/user.module').then(m =&gt; m.UserModule) ` (2认同)

nav*_*ath 10

以下是我在使用带有惰性路由的canLoadcanActivete时发现的案例:

A) 如果使用 canLoad 或 canActivate:

1. 当模块尚未下载时:

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
Run Code Online (Sandbox Code Playgroud)

2. 当模块已经下载时

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
Run Code Online (Sandbox Code Playgroud)

B) 如果同时使用 canLoad 和 canActivate:

1. 当模块尚未下载时:

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
Run Code Online (Sandbox Code Playgroud)

2. 当模块已经下载时

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
Run Code Online (Sandbox Code Playgroud)

因此,我更喜欢对惰性模块使用 canLoad 和 canActivate,对基于组件的路由使用 canActivate


小智 5

值得注意的是,canLoad不会阻止某人获取您的源代码。除非用户获得授权,否则浏览器不会下载 .js,但您可以通过在浏览器控制台上发出 import('./xxxxx.js') 来强制手动下载。

模块名称可以在路由定义的 main.js 中轻松找到。