Un guard es un servicio que permite controlar el acceso a rutas en Angular. Puedes pensar en un guard como una barrera de seguridad que decide si un usuario puede o no acceder a una ruta específica en la aplicación. Un guard puede ser usado, por ejemplo, para verificar si el usuario está autenticado antes de acceder a una página protegida, o si tiene ciertos permisos o roles.
Angular proporciona varios tipos de guards que puedes usar en distintas situaciones:
Para crear un guard en Angular, puedes usar el Angular CLI, que genera automáticamente la estructura básica del guard. Sigue estos pasos:
En primer lugar, abre tu terminal en el proyecto Angular y ejecuta el siguiente comando:
ng generate guard guards/auth
En este ejemplo, estamos creando un guard llamado auth
en una carpeta llamada guards
. El Angular CLI generará dos archivos:
auth.guard.ts
: Donde implementarás la lógica del guard.
auth.guard.spec.ts
: Archivo para pruebas unitarias del guard.
El archivo auth.guard.ts
será algo como lo siguiente:
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(): boolean {
if (this.authService.isAuthenticated()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
En este caso, el guard utiliza un servicio de autenticación (AuthService
) para verificar si el usuario está autenticado. Si el usuario no está autenticado, se redirige a la página de inicio de sesión (/login
).
Para aplicar el guard a una ruta, debes modificar el archivo de configuración de rutas (app-routing.module.ts
o el que uses en tu proyecto). A continuación, un ejemplo de cómo hacerlo:
const routes: Routes = [
{
path: 'dashboard',
component: DashboardComponent,
canActivate: [AuthGuard]
},
{
path: 'login',
component: LoginComponent
}
];
En este caso, estamos protegiendo la ruta /dashboard
con el guard AuthGuard
. Si el guard retorna false
, el usuario será redirigido a la ruta /login
.
Como mencionamos anteriormente, Angular proporciona diferentes tipos de guards, cada uno con una funcionalidad específica.
El guard CanActivate se utiliza para verificar si el usuario puede activar una ruta. Un caso típico es proteger rutas de la aplicación que requieren autenticación. Ya hemos visto un ejemplo de este guard en la sección anterior.
El guard CanDeactivate se utiliza cuando necesitas controlar si un usuario puede salir de una ruta. Es útil, por ejemplo, si tienes un formulario con datos sin guardar y quieres advertir al usuario antes de que abandone la página.
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
@Injectable({
providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate): Observable<boolean> | Promise<boolean> | boolean {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
Este guard necesita que el componente que protege implemente el método canDeactivate
, que devolverá true
o false
dependiendo de si el usuario puede salir o no de la página.
Este guard se utiliza para proteger rutas hijas dentro de un módulo. Funciona de manera similar al CanActivate, pero se aplica específicamente a rutas secundarias (child routes).
const routes: Routes = [
{
path: 'admin',
component: AdminComponent,
canActivateChild: [AuthGuard],
children: [
{
path: 'users',
component: UsersComponent
}
]
}
];
El guard CanLoad se utiliza para prevenir que un módulo perezoso (lazy-loaded) se cargue si no se cumplen ciertas condiciones. Es útil cuando quieres cargar módulos solo si el usuario está autenticado o tiene permisos específicos.
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
canLoad: [AuthGuard]
}
1. Mantén los Guards Simples: No sobrecargues la lógica de los guards. Su propósito principal es decidir si se puede o no acceder a una ruta. Cualquier lógica compleja debería estar en servicios externos.
2. Usa Servicios para la Lógica de Negocios: Los guards deben delegar la mayor parte de la lógica a servicios dedicados (por ejemplo, un servicio de autenticación o de permisos).
3. Desactiva Rutas cuando Sea Necesario: Usa guards como CanDeactivate
para evitar la pérdida de datos. Esto es especialmente útil en formularios donde el usuario podría haber ingresado información importante.
4. Usa Guards en Conjunto: Puedes combinar diferentes guards para cubrir varios casos de uso. Por ejemplo, puedes usar tanto CanActivate como CanLoad en una misma aplicación para proteger las rutas y módulos.
Implementar guards en Angular es una excelente manera de mejorar la seguridad y control de acceso en tu aplicación. Te permiten gestionar el acceso a las rutas de forma sencilla, ya sea que necesites proteger rutas individuales, grupos de rutas hijas o módulos enteros. Siguiendo las mejores prácticas y utilizando los tipos de guards adecuados, podrás construir aplicaciones más seguras y robustas.
Jorge García
Fullstack developer