Skip to Content

Sistema de Guards

Creative Minds implementa un robusto sistema de protección basado en guards que aseguran el acceso adecuado a diferentes partes de la aplicación.

Concepto de Guards

Los guards son clases que implementan lógica de protección y autorización. Pueden verificar:

  • Autenticación del usuario
  • Roles y permisos
  • Estado de onboarding
  • Suscripciones activas
  • Otros requisitos de acceso

Implementación Base

Guard Base

// shared/utils/guard.ts export class Guard { constructor( protected name: string ) {} protected protect({ condition, redirectTo }: { condition: boolean, redirectTo: string }) { if (condition) { redirect(redirectTo); } } }

Guards Específicos

1. Auth Guard

// modules/auth/guards/auth.guard.ts class AuthGuard extends Guard { constructor( name: string, private authService: AuthService ) { super(name); this.logger = new Logger(name + "Guard"); } // Protección básica de autenticación async protectByAuth({ redirectTo }: { redirectTo: string }) { const { sub } = await this.authService.getCurrentUser(); this.protect({ redirectTo, condition: !sub, }); } // Protección por rol async protectByAuthAndRole({ roles, redirectTo }: ProtectByRoleProps) { const { sub, role } = await this.authService.getCurrentUser(); // Verifica autenticación this.protect({ redirectTo: redirectTo || "/login", condition: !sub, }); // Verifica rol this.protect({ redirectTo: redirectTo || "/login", condition: !role || !roles.includes(role), }); } } export const authGuard = new AuthGuard("auth", authService);

2. Onboarding Guard

// modules/onboarding/guards/onboarding.guard.ts class OnboardingGuard extends Guard { constructor( name: string, private onboardingService: OnboardingService ) { super(name); this.logger = new Logger(name + "Guard"); } async protectByOnboarding({ redirectTo }: { redirectTo: string }) { const onboarding = await this.onboardingService.getCurrentUserOnboarding(); this.protect({ redirectTo, condition: !onboarding?.completed, }); } } export const onboardingGuard = new OnboardingGuard( "onboarding", onboardingService );

Uso en la Aplicación

1. En Layouts

// app/(core)/dashboard/layout.tsx export default async function DashboardLayout({ children, }: { children: React.ReactNode }) { // Protección por autenticación await authGuard.protectByAuth({ redirectTo: "/login", }); // Protección por onboarding await onboardingGuard.protectByOnboarding({ redirectTo: "/onboarding", }); return ( <div className="flex h-screen"> <SidebarFeat /> {children} </div> ); }

2. En Server Actions

// modules/users/actions/profile.action.ts export async function updateProfileAction(data: ProfileData) { // Verifica autenticación y rol await authGuard.protectByAuthAndRole({ roles: ["employee", "admin"], redirectTo: "/unauthorized" }); // Procede con la actualización return userService.updateProfile(data); }

Middleware Integration

El sistema de guards se complementa con el middleware de Next.js:

// middleware.ts import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' import { updateSession } from './providers/database/supabase/middleware' export async function middleware(request: NextRequest) { // Actualiza la sesión en cada request return await updateSession(request) } export const config = { matcher: [ // Excluye recursos estáticos '/((?!_next/static|_next/image|favicon.ico).*)', ], }

Mejores Prácticas

  1. Granularidad: Crear guards específicos para cada tipo de protección

  2. Composición: Combinar múltiples guards cuando sea necesario

  3. Logging: Mantener logs de intentos de acceso no autorizado

  4. Mensajes claros: Proporcionar feedback útil al usuario

  5. Flexibilidad: Permitir configuración de redirects y comportamientos

  6. Performance: Minimizar llamadas innecesarias a servicios externos

Diagrama de Flujo

Este sistema de guards proporciona una capa de seguridad robusta y flexible, permitiendo proteger diferentes aspectos de la aplicación de manera modular y mantenible.

Last updated on