Asegurando TuTiendaWeb: Gestión Robusta de Autenticación y Claims con Firebase
Para cualquier plataforma de comercio electrónico, la autenticación de usuarios y la gestión de permisos son pilares críticos. En TuTiendaWeb, nos enfrentamos al desafío de construir un sistema de autenticación flexible y seguro que no solo identificara a los usuarios, sino que también gestionara sus roles y la tienda asociada de manera eficiente. Este post detalla la culminación de la Fase 2 del proyecto, centrada en una sólida gestión de autenticación (Auth) y claims de usuario con Firebase.
Entendiendo la Gestión de Claims
Más allá de saber quién es un usuario, a menudo necesitamos saber qué puede hacer o a qué recursos tiene acceso. Aquí es donde entran en juego los claims. Para TuTiendaWeb, esto significó asignar un storeId y un role específico a cada usuario, permitiendo así una autorización granular. Implementamos un auth.service centralizado para manejar estas operaciones.
import { getAuth } from 'firebase-admin/auth';
interface UserClaims {
storeId?: string;
role?: 'admin' | 'seller' | 'customer';
}
export async function setUserClaims(uid: string, claims: UserClaims): Promise<void> {
try {
await getAuth().setCustomUserClaims(uid, claims);
console.log(`Claims actualizados para el usuario ${uid}`);
} catch (error) {
console.error('Error al establecer claims:', error);
throw error;
}
}
Persistencia y Acceso a Claims
La información de los claims debe ser accesible rápidamente y de forma segura. Utilizamos los tokens de autenticación de Firebase para almacenar los claims primarios. Sin embargo, para una mayor flexibilidad o en escenarios donde el token podría no ser suficiente (por ejemplo, al crear nuevos claims que aún no se han propagado al token actual), implementamos un fallback a Firestore. Esto asegura que la sesión del servidor siempre tenga la información de claims más actualizada.
import { getAuth } from 'firebase-admin/auth';
import { getFirestore } from 'firebase-admin/firestore';
export async function getUserClaims(uid: string): Promise<UserClaims | null> {
try {
const userRecord = await getAuth().getUser(uid);
if (userRecord.customClaims) {
return userRecord.customClaims as UserClaims;
} else {
// Fallback a Firestore si no hay claims personalizados en el token
const userDoc = await getFirestore().collection('users').doc(uid).get();
return userDoc.data()?.claims as UserClaims || null;
}
} catch (error) {
console.error('Error al obtener claims:', error);
return null;
}
}
Flujo de Usuario Completo y Onboarding
Un aspecto clave fue asegurar una experiencia de usuario fluida desde el registro hasta la asignación de roles. El flujo diseñado para TuTiendaWeb guía al usuario a través del registro, seguido de un proceso de onboarding donde se define su storeId y role inicial. Solo después de completar este onboarding, los claims son establecidos de forma permanente, lo que permite al usuario interactuar plenamente con la plataforma según sus permisos.
Validación con Pruebas de Integración
La fiabilidad de la autenticación y los claims es primordial. Por ello, se invirtió significativamente en pruebas de integración, utilizando Vitest, para simular escenarios reales. Esto incluyó el flujo completo de registro, onboarding y verificación de claims, asegurando que setUserClaims, getUserClaims y updateUserClaims funcionaran correctamente contra el emulador de Auth, y que getServerSession recuperara los claims esperados del token o de Firestore.
import { describe, it, expect } from 'vitest';
import { getAuth } from 'firebase-admin/auth';
import { setUserClaims, getUserClaims } from '../src/auth.service'; // Asumiendo auth.service
describe('Auth Claims Integration', () => {
it('should set and retrieve custom claims correctly', async () => {
const testUid = 'test-user-claims-123';
await getAuth().createUser({ uid: testUid, email: '[email protected]' });
const claims = { storeId: 'tienda-001', role: 'seller' };
await setUserClaims(testUid, claims);
// Esperar un breve momento para la propagación del claim si es necesario
// En un entorno emulado, esto suele ser instantáneo
const retrievedClaims = await getUserClaims(testUid);
expect(retrievedClaims).toEqual(expect.objectContaining(claims));
});
});
Conclusión
La integración de un auth.service robusto, apoyado por Firebase Auth y Firestore para la gestión de claims, ha fortalecido significativamente el sistema de seguridad y permisos de TuTiendaWeb. La finalización de la Fase 2 marca un hito importante, asegurando que la plataforma pueda escalar y manejar diversas interacciones de usuario con confianza. El énfasis en pruebas de integración exhaustivas con Vitest garantiza la fiabilidad de estos flujos críticos.
Próximos Pasos
Considera implementar una interfaz de administración para gestionar roles y claims, y explora la integración de reglas de seguridad de Firestore basadas en estos claims para una autorización aún más fina en el lado del servidor.
Generated with Gitvlg.com