¿Diferencia entre canLoad y canActivate de Angular?

100

¿Cuál es la diferencia entre canLoady 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;
}

¿Cuándo debería cuál de ellos?

Yoav Schniederman
fuente

Respuestas:

99

canActivate se utiliza para evitar que usuarios no autorizados accedan a determinadas rutas. Consulte los documentos para obtener más información.

canLoad se utiliza para evitar que la aplicación cargue módulos completos de forma perezosa si el usuario no está autorizado para hacerlo.

Consulte los documentos y el ejemplo a continuación para obtener más información.

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

Con este código, el código para AdminModule solo se cargará en la aplicación si AuthGuard regresa true.

Si el usuario no está autorizado para acceder a esta ruta, y solo hubiéramos usado un canActivateguardia, AdminModulese cargaría, aunque el usuario no podría acceder a esa ruta.

Fredrik Lundin
fuente
6
Si lo uso canActivateen el escenario anterior, ¿cuál será la diferencia?
k11k2
3
Se cargará @ k11k2 con el canActivemódulo (F12> Fuentes - en Chrome). Puede ver los archivos .js allí.Con canLoadestos módulos (archivos .js) no se cargarán :) Verifique mi respuesta anterior donde lo expliqué mejor
DiPix
23
¿Qué pasa con el escenario en el que el administrador inició sesión, por lo que el módulo de administración se cargó a través de canLoaddevuelve verdadero y luego cierra la sesión de la aplicación? Ahora, un usuario que no es administrador inicia sesión en el mismo navegador, ¿cómo funciona? ¿El módulo cargado fue desalojado o eliminado de la caché?
Keerthivasan
2
@Keerthivasan nada obliga a eliminar la parte previamente cargada del módulo de administración perezoso cuando un usuario cierra sesión y vuelve a iniciar sesión con una cuenta diferente que no tiene suficiente permiso para cargar el módulo de administración. Sin embargo, no obtendrá acceso de todos modos ... excepto si tiene un módulo en caché cargado. No creo que sea un problema de seguridad real, ya que generalmente un dispositivo es un usuario real
hastrb
1
@ sgClaudia98 puedes usar ambos, pero hay un estricto orden de ejecución de los guardias. es por eso que no hay diferencia en su caso con respecto a lo que dije un poco antes. Creo que puse una explicación muy detallada en mi primer comentario. Ese sería un caso bastante extraño si hoy en día hay un dispositivo y el inicio de sesión de administrador / no administrador uno por uno.
hastrb
36
  • CanActivate : decide si se puede activar una ruta, esta protección puede no ser la mejor manera para los módulos de funciones que tienen carga diferida, ya que esta protección siempre cargará el módulo en la memoria, incluso si la protección devolvió falso, lo que significa que el usuario no tiene autorización para acceder. la ruta.
  • CanLoad : decide si un módulo se puede cargar de forma perezosa, controla si se puede cargar una ruta. Esto resulta útil para los módulos de funciones que se cargan de forma diferida. Ni siquiera se cargarán si el guardia devuelve falso.

Esta es una prueba que hice en ambos guardias con un módulo de funciones que se carga de forma diferida:

1. Prueba CanActivate Guard

Notará en la parte inferior de la página de Red que realizó 24 solicitudes con un tamaño de 9.5 MB transferidas terminando en 3.34 segundos y completamente cargadas en 3.47 segundos.

Prueba CanActivate Guard en el módulo de funciones de carga diferida

1. Prueba CanLoad Guard

aquí verá la gran diferencia cuando usamos CanLoad Guard ya que el navegador hizo solo 18 solicitudes con un tamaño de 9.2 MB transferidas terminando en 2.64 segundos y completamente cargado 2.59 segundos.

Prueba CanLoad Guard en el módulo de funciones de carga diferida

CanLoad Guard nunca carga los datos del módulo si el usuario no está autorizado y eso le da más rendimiento ya que el tiempo de carga disminuyó casi 1 segundo y eso es un tiempo enorme en la carga de páginas web, sin duda depende del tamaño del módulo.

Consejo: si desea realizar la prueba en su proyecto, asegúrese de que la Disable Cachecasilla de verificación en la pestaña de red esté marcada, está marcada en la primera imagen

Mahmoud Fawzy
fuente
3
Solo para no confundir a alguien ... 403 está prohibido, no no autorizado, que es 401.
hastrb
20

Con respecto a la pregunta de los comentarios en otra publicación "Si uso canActivate en el escenario anterior, ¿cuál será la diferencia?"

En realidad, para el usuario no habrá diferencia, no tendrá acceso a la página en ambos casos. Aunque hay una diferencia oculta . Si presiona F12 y se mueve a Fuentes (en Chrome) donde están los archivos de descarga. Luego puede ver que en caso de que se haya descargado el archivo canActive con código ( chunk.js ). Incluso si no tiene acceso a la página. ingrese la descripción de la imagen aquí

Pero en el caso de canLoad, no habrá ningún archivo chunk.js con código fuente.

ingrese la descripción de la imagen aquí

Como puede ver, esto tiene un gran impacto en la seguridad.

Y, por supuesto, no olvide que canLoad solo se puede usar para módulos LazyLoaded .

DiPix
fuente
3
no puedo ver ningún fragmento del módulo de carga diferida en mi pestaña de red, pero las rutas funcionan como se esperaba, ¿cómo puedo confirmar que mis módulos se cargan a pedido o no?
k11k2
@ k11k2 si desea ver de qué archivo forma parte un módulo, simplemente agregue una debugger;declaración en el constructor para uno de los componentes de ese módulo. Luego puede ver si se cargó como un fragmento separado o se incluyó en un módulo como main. Si tiene referencias a componentes en un módulo diferido que no están aislados de ese módulo, es posible que se cargue de todos modos. Si ve esto, sugiere que está filtrando por algo que no sea archivos JS, o necesita dividir su módulo perezoso en partes comunes y 'verdaderamente perezosas'.
Simon_Weaver
@ k11k2 Creo que su "módulo de carga diferida" no se está cargando de forma diferida. Asegúrese de haber utilizado la loadChildrenpropiedad como parte de la ruta a su módulo perezoso.
hastrb
16

canActivate se utiliza para evitar que un usuario no autorizado

canLoad se utiliza para evitar que todo el módulo de la aplicación

Ejemplo de canActivate :

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

Ejemplo de canLoad :

{ path: 'user' , canLoad: [AuthenticGuard], loadChildren : './user/user.module#UserModule' }
Sagar Jadhav
fuente
Para los futuros lectores, el ejemplo de canActive no es flojo, pero canLoad es ... debido a tener loadChildren. Además, una versión reciente de angular es ..loadChildren: () => import('./user/user.module').then(m => m.UserModule)
hastrb
Explicación muy simple, me gustó :)
KTM
16

El CanLoad Guardia evita que la carga del módulo cargado perezoso. Generalmente usamos esta protección cuando no queremos que un usuario no autorizado navegue a alguna de las rutas del módulo y también se detenga y luego incluso vea el código fuente del módulo.

El Angular proporciona canActivate Guard, que evita que usuarios no autorizados accedan a la ruta. Pero no impide que se descargue el módulo. El usuario puede utilizar la consola de desarrollo de Chrome para ver el código fuente. CanLoad Guard evita que se descargue el módulo.

En realidad, CanLoad protege la carga de un módulo, pero una vez que se carga el módulo, CanLoad guard no hará nada. Supongamos que hemos protegido la carga de un módulo utilizando CanLoad guard para usuarios no autenticados. Cuando el usuario inicie sesión, ese módulo será aplicable para ser cargado y podremos navegar por las rutas secundarias configuradas por ese módulo. Pero cuando el usuario cierra la sesión, aún el usuario podrá navegar por esas rutas secundarias porque el módulo ya está cargado. En este caso, si queremos proteger las rutas de los niños de los usuarios no autorizados, también necesitamos utilizar CanActivate guard.

Utilice CanLoad antes de cargar AdminModule:

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

Después de cargar AdminModule, en el módulo AdminRouting podemos usar CanActive para proteger a los niños de usuarios no autorizados como a continuación:

{ 
      path: '',
      component: AdminComponent,
      children: [ 
        {
          path: 'person-list',
          component: PersonListComponent,
          canActivate: [ AuthGuardService ]
        }
      ]
    }  
Mohammad niazmand
fuente
Entonces, ¿uno debería usar canLoad y canActivate?
Tarida George
0

canActivate si un usuario no autorizado ingresa aún carga ese módulo. necesita canLoad para juzgar si es necesario cargarlo.

LiHao
fuente
0

Es importante notar que canLoad no impedirá que alguien obtenga su código fuente. El .js no se descargará mediante el navegador a menos que el usuario esté autorizado, pero puede forzar una descarga manual emitiendo una importación ('./ xxxxx.js') en la consola del navegador.

El nombre del módulo se puede encontrar fácilmente en main.js en la definición de rutas.

Ivan Muricy
fuente