Guardias canActivate en Angular: Proteger rutas con autenticación

Clase 63 de 80Curso de Angular 4

Resumen

Controla el acceso y la visibilidad de tu interfaz en Angular con total claridad. Aquí verás cómo usar AngularFireAuth, authState, ngIf y un guardia canActivate para mostrar u ocultar elementos según el estado de sesión, y cómo impedir el acceso por URL a vistas restringidas. Además, se explica el rol del JSON Web Token en local storage y el ajuste de reglas de lectura y escritura.

¿Cómo controlar la UI con ngIf y authState?

Para decidir qué ve un usuario según si está logueado, se aprovecha authState de AngularFireAuth. Este stream existe solo cuando hay sesión activa y expone un identificador único (UID).

  • Idea clave: authState indica si hay usuario autenticado.
  • Variable de estado: loggedIn = false para controlar la vista.
  • Visibilidad condicional: usar ngIf para mostrar u ocultar login y registro.

¿Qué hace la función isLogged?

  • Función pública: isLogged devuelve el stream de autenticación.
  • Origen de datos: usa el objeto de autorización y su authState.
  • Inicio temprano: se invoca desde el constructor para escuchar desde que abre la app.
// autorizacion.service.ts
public isLogged() {
  return this.angularFireAuth.authState;
}

¿Cómo suscribirte a authState y manejar errores?

  • Suscripción: llamar a isLogged().subscribe(...).
  • Éxito: si result y result.uid existen, loggedIn = true.
  • Alternativas: si no hay result o no hay UID, loggedIn = false.
  • Error: por seguridad, cualquier error implica loggedIn = false.
// app.component.ts
loggedIn = false;

constructor(private autorizacionService: AutorizacionService) {
  this.autorizacionService.isLogged().subscribe({
    next: (result) => {
      if (result && result.uid) {
        this.loggedIn = true;
      } else {
        this.loggedIn = false;
      }
    },
    error: () => {
      this.loggedIn = false;
    }
  });
}

¿Cómo ocultar login y registro con ngIf?

  • Ubicación: en app.component.html donde está la barra de navegación.
  • Regla visual: si está logueado, ocultar login y registro; si no, mostrarlos.
<!-- app.component.html -->
<ul *ngIf="!loggedIn">
  <!-- enlaces de login y registro -->
</ul>
  • Verificación rápida: al iniciar sin sesión se muestran login y registro; tras el login, se ocultan automáticamente.

¿Cómo configurar reglas de lectura y escritura?

A nivel de base de datos, se puede permitir lectura pública para maximizar vistas, dejando escritura solo con autorización.

  • Lectura abierta: regla de lectura en true.
  • Escritura restringida: requiere autenticación.
  • Efecto práctico: aunque no haya sesión, el listado se carga tras refresh; sin sesión, no se puede escribir.

¿Qué es un guardia canActivate y cómo protege rutas?

Aunque ocultes botones, alguien podría escribir la URL directa. Un guardia evita el acceso a rutas cuando no hay sesión, incluso si se conoce el path.

  • Comportamiento: si no hay sesión, no navega; con sesión, sí.
  • Ventaja: protección robusta a nivel de rutas.
  • Escenario: bloquea accesos alternos, no solo botones.

¿Cómo crear el servicio MyGuard?

  • Naturaleza: es un service con decorador @Injectable.
  • Dependencias: reutiliza la lógica de isLogged y la variable loggedIn.
  • Regla de acceso: canActivate retorna this.loggedIn.
// my-guard.service.ts
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { AutorizacionService } from './autorizacion.service';

@Injectable()
export class MyGuard implements CanActivate {
  private loggedIn = false;

  constructor(private autorizacionService: AutorizacionService) {
    this.autorizacionService.isLogged().subscribe({
      next: (r) => { this.loggedIn = !!(r && r.uid); },
      error: () => { this.loggedIn = false; }
    });
  }

  canActivate(): boolean {
    return this.loggedIn;
  }
}

¿Cómo activarlo en app.module.ts y rutas?

  • Registro del servicio: agregar MyGuard en providers de app.module.ts.
  • Protección de rutas: añadir canActivate: [MyGuard] en las rutas restringidas, por ejemplo la de crear.
// app.module.ts (fragmento)
import { MyGuard } from './my-guard.service';

@NgModule({
  providers: [MyGuard]
})
export class AppModule {}

// app-routing (fragmento)
{
  path: 'crear',
  component: CrearComponent,
  canActivate: [MyGuard]
}
  • Prueba final: sin sesión, no permite navegar ni con la URL directa; con sesión, el acceso se concede normalmente.

Palabras clave y habilidades trabajadas: JSON Web Token en local storage, authState y stream de autenticación, control visual con ngIf, manejo de errores en subscribe, reglas de lectura y escritura en base de datos, uso de guardia canActivate, configuración en providers y rutas, y navegación protegida por URL y path.

¿Te gustaría que profundicemos en el flujo de logout o en estrategias de redirección tras el login? Comparte tus dudas y casos de uso en los comentarios.

      Guardias canActivate en Angular: Proteger rutas con autenticación