Skip to main content

Overview

The publicGuard is an Angular route guard that protects public routes (like login and registration pages) from authenticated users. It redirects logged-in users to their appropriate dashboard based on their role, preventing them from accessing authentication pages when already authenticated.

Signature

export const publicGuard: CanActivateFn

Type Definition

type CanActivateFn = (
  route: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
) => boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree>

Implementation

import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { TokenStorageService } from '../services/token-storage.service';

export const publicGuard: CanActivateFn = (route, state) => {
  const tokenStorage = inject(TokenStorageService);
  const router = inject(Router);

  // Obtiene el token
  const token = tokenStorage.getToken();

  // Si el usuario está logueado
  if (token) {
    // Obtiene el rol guardado en localStorage
    const role = localStorage.getItem('role');

    // Redirección
    if (role === 'ROLE_ADMIN') {
      router.navigate(['/libros']);
    } else {
      router.navigate(['/catalogo']);
    }

    return false; // bloquea acceso a /auth/login
  }

  // Permite acceso a login/registro
  return true;
};

Parameters

route
ActivatedRouteSnapshot
Contains information about the route being activated
state
RouterStateSnapshot
Contains the router state at a particular moment in time

Return Value

return
boolean
  • true - User is not authenticated, allow access to public route
  • false - User is authenticated, redirect based on role

Redirect Behavior

When an authenticated user tries to access a public route, they are redirected based on their role:
RoleRedirect Destination
ROLE_ADMIN/libros (Books management)
Other roles/catalogo (Public catalog)
No role/catalogo (Public catalog)

Usage

Route Configuration

Apply the publicGuard to authentication and public routes:
import { Routes } from '@angular/router';
import { publicGuard } from './core/guards/public-guard';

export const routes: Routes = [
  {
    path: 'auth',
    canActivate: [publicGuard],
    children: [
      {
        path: 'login',
        loadComponent: () => import('./pages/auth/login/login.component')
      },
      {
        path: 'registro',
        loadComponent: () => import('./pages/auth/registro/registro.component')
      }
    ]
  },
  {
    path: 'welcome',
    loadComponent: () => import('./pages/welcome/welcome.component'),
    canActivate: [publicGuard]
  }
];

Protecting Authentication Routes

The most common use case is protecting login/registration pages:
{
  path: 'auth/login',
  component: LoginComponent,
  canActivate: [publicGuard]  // Redirect if already logged in
}

How It Works

  1. Token Check (src/app/core/guards/public-guard.ts:10): Retrieves authentication token from TokenStorageService
  2. Authentication Status:
    • Authenticated (token exists):
      • Retrieves user role from localStorage (src/app/core/guards/public-guard.ts:15)
      • Redirects to role-specific route
      • Returns false to block access
    • Not Authenticated (no token):
      • Returns true to allow access to the public route

Dependencies

  • TokenStorageService (src/app/core/guards/public-guard.ts:6): Service for managing authentication tokens
  • Router (src/app/core/guards/public-guard.ts:7): Angular router for navigation
  • localStorage: Browser API for retrieving user role
This guard implements the inverse logic of authGuard. While authGuard protects authenticated routes, publicGuard protects public routes from authenticated users.

When to Use

Use publicGuard when you need to:
  • Prevent logged-in users from accessing login/registration pages
  • Implement automatic redirection based on user role after login
  • Create landing pages that should only be visible to unauthenticated users
  • Improve user experience by avoiding unnecessary authentication steps

User Experience Benefits

Better UX: If a user tries to access /auth/login while already logged in, they are automatically redirected to their appropriate dashboard instead of seeing the login form unnecessarily.

Example Scenarios

  1. User bookmarks login page: An authenticated user who bookmarked /auth/login will be automatically redirected to their dashboard instead of seeing the login form
  2. Back button after login: If a user presses the back button after logging in, they won’t return to the login page but will be redirected appropriately
  3. Direct URL access: Authenticated users cannot manually navigate to authentication pages by typing the URL

Role-Based Redirection

The guard implements smart redirection based on user roles:
if (role === 'ROLE_ADMIN') {
  router.navigate(['/libros']);      // Admin → Books management
} else {
  router.navigate(['/catalogo']);    // Regular user → Catalog
}
This ensures users land on the most relevant page for their role.
The redirect destinations are hardcoded in the guard. If you need to change the default landing pages for different roles, you’ll need to modify the guard implementation at src/app/core/guards/public-guard.ts:18-22.

Complete Authentication Flow

Combine all three guards for a complete authentication system:
export const routes: Routes = [
  // Public routes - only for unauthenticated users
  {
    path: 'auth',
    canActivate: [publicGuard],
    children: [
      { path: 'login', component: LoginComponent },
      { path: 'registro', component: RegistroComponent }
    ]
  },
  
  // User routes - requires authentication
  {
    path: 'catalogo',
    component: CatalogoComponent,
    canActivate: [authGuard]
  },
  
  // Admin routes - requires authentication + admin role
  {
    path: 'libros',
    component: LibrosComponent,
    canActivate: [authGuard, adminGuard]
  }
];

Build docs developers (and LLMs) love