Mejorando Pruebas de Autenticación con Firebase Emulators y Custom Claims en TuTiendaWeb
Introducción
En el proyecto TuTiendaWeb, la autenticación robusta y la gestión de sesiones son pilares fundamentales para la seguridad y la experiencia del usuario. A medida que la aplicación evoluciona, garantizar que estos flujos funcionen impecablemente se vuelve crítico, especialmente en entornos de prueba. Recientemente, nos enfocamos en fortalecer nuestras pruebas de integración para cubrir escenarios complejos de autenticación, incluyendo el uso de custom claims (reclamaciones personalizadas) y la validación de sesiones en el servidor.
El Desafío
Probar la autenticación en aplicaciones modernas con características como custom claims de Firebase y la necesidad de validar sesiones en el lado del servidor (getServerSession) puede ser complicado. Los desafíos incluyen:
- Simulación de Usuarios y Roles: ¿Cómo crear usuarios de prueba con roles específicos (custom claims) de manera programática para cada ejecución de prueba?
- Entorno de Prueba Consistente: Asegurar que el entorno de autenticación sea aislado y predecible para evitar interferencias entre pruebas.
- Validación de Sesiones: Verificar que el backend maneje correctamente los tokens de ID con custom claims y establezca sesiones seguras.
La Solución
Implementamos una estrategia de pruebas de integración utilizando los Firebase Emulators para la autenticación. Esto nos permitió simular un entorno de autenticación de Firebase completo y aislado. La clave fue la capacidad de interactuar con el Auth Emulator directamente a través de su API REST para "mintear" (generar) tokens de ID con custom claims específicos para usuarios de prueba. Estos tokens son luego utilizados en las solicitudes de prueba para simular usuarios autenticados.
El flujo de pruebas incluye:
- Configuración del Usuario de Prueba: Registrar un usuario en el Auth Emulator.
- Generación de Custom Claims: Utilizar la API REST del emulador para añadir custom claims a este usuario.
- Minting de ID Token: Obtener un ID token para el usuario, que ahora incluirá los custom claims.
- Validación de Sesión en el Servidor: Enviar este ID token a un endpoint de la aplicación que utiliza
getServerSession(o similar) para procesar la sesión. Esto valida que la lógica del servidor maneje correctamente el token y sus reclamaciones.
Así es como se puede interactuar con el Firebase Auth Emulator para mintear un token con custom claims para una prueba:
import { initializeApp, getApps, cert } from 'firebase-admin/app';
import { getAuth } from 'firebase-admin/auth';
import axios from 'axios';
// Asegura que Firebase Admin SDK esté inicializado (para emulador)
if (!getApps().length) {
initializeApp({
projectId: 'tu-proyecto-id',
// Para el emulador, no es necesario un serviceAccountKey real
// 'credential': cert(require('./path/to/serviceAccountKey.json'))
});
}
async function mintTokenWithCustomClaims(uid: string, claims: Record<string, any>): Promise<string> {
// Establecer custom claims para el usuario en el emulador
await getAuth().setCustomUserClaims(uid, claims);
// Obtener el ID token para el usuario con los claims actualizados
// Esto típicamente se haría desde el cliente, pero para pruebas
// y simular el flujo completo, podemos usar la API REST del emulador
const emulatorHost = 'http://127.0.0.1:9099'; // Puerto por defecto del Auth Emulator
const response = await axios.post(`${emulatorHost}/identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=tu-api-key`, {
token: await getAuth().createCustomToken(uid),
returnSecureToken: true,
});
return response.data.idToken;
}
// Ejemplo de uso en una prueba
async function testAuthenticatedFlow() {
const testUid = 'test-user-123';
const testClaims = { storeId: 'tienda-001', role: 'admin' };
const idToken = await mintTokenWithCustomClaims(testUid, testClaims);
// Ahora usa 'idToken' en tu solicitud HTTP de prueba al backend
// para verificar que getServerSession lo procese correctamente.
console.log('ID Token minteado con claims:', idToken);
}
testAuthenticatedFlow();
Este enfoque garantiza que nuestras acciones como registerAction y checkSlugAvailabilityAction sean probadas bajo condiciones realistas de autenticación y autorización.
Decisiones Clave
- Uso de Firebase Emulators: Permite pruebas aisladas y rápidas sin consumir recursos de producción o incurrir en costos.
- API REST para Tokens: Interacción directa con el Auth Emulator a través de su API REST para manipular usuarios y mintear tokens simplifica enormemente la preparación del estado de prueba.
- Cobertura Exhaustiva: El enfoque permitió un incremento significativo en la cobertura de pruebas de integración, con 93 tests y 6 suites dedicadas a la autenticación y sesiones.
Resultados
La implementación de esta estrategia de pruebas nos permitió cerrar con éxito la Fase 2 del desarrollo, validando la robustez de los sistemas de autenticación y gestión de sesiones. Obtuvimos una mayor confianza en la lógica de nuestra aplicación, especialmente en la forma en que maneja los permisos y los datos de sesión de los usuarios.
Lecciones Aprendidas
Las pruebas de integración son vitales para sistemas complejos como la autenticación. Aprovechar herramientas como los Firebase Emulators y sus APIs programáticas puede simplificar enormemente la creación de escenarios de prueba realistas y repetibles, ahorrando tiempo y mejorando la calidad del código. Asegúrate siempre de simular tu entorno lo más fielmente posible en tus pruebas.
Generated with Gitvlg.com