Autenticar usuarios y proteger las rutas de una aplicación móvil es una de las tareas más comunes —y más críticas— en el desarrollo con Ionic y Angular. Aquí se explica paso a paso cómo conectar una pantalla de login con el backend, almacenar el JSON Web Token en el navegador y configurar un interceptor HTTP que adjunte automáticamente ese token a cada petición saliente.
¿Cómo se conecta la pantalla de login con el servicio de autenticación?
El punto de partida es una pantalla de login ya construida y un AuthenticationService con métodos de login y sign up. En el archivo homepage.ts se crea una función doLogin que centraliza toda la lógica de autenticación [0:28].
- Se inyecta
AuthenticationService en el constructor como dependencia privada.
- Es necesario registrar ese servicio en el arreglo
providers del archivo app.module.ts para que Angular lo reconozca [1:08].
Dentro de doLogin se invoca this.authenticationService.login() pasándole un objeto con las propiedades email y password extraídas del formulario de credenciales [1:26].
¿Qué ocurre con la respuesta del backend?
Al llamar a .subscribe() sobre el observable que devuelve el servicio, se manejan dos caminos:
- Éxito: se recibe
data que contiene el token. Se imprime con console.log para verificar la respuesta y luego se almacena.
- Error: se muestra un
alert con el mensaje "No pudimos autenticarte" y se imprime el error en consola para depuración [1:55].
El token se guarda utilizando localStorage, un objeto global de JavaScript que permite almacenar datos de forma persistente en el navegador. Se usa localStorage.setItem('jwt', data.token) donde 'jwt' es el identificador del espacio de almacenamiento [2:24]. Como TypeScript no reconoce la propiedad token dentro de data, se anota el parámetro con el tipo any para evitar errores de compilación.
¿Cómo se maneja la navegación después del login?
Una vez almacenado el token, la aplicación redirige al usuario a la pantalla de rights mediante NavController. En lugar de usar .push(), que apila pantallas en el historial y permite volver atrás con el botón back de Android, se utiliza navigateRoute [3:18].
.push() conserva la pantalla anterior en la pila de navegación.
navigateRoute reemplaza el estado actual, eliminando la posibilidad de regresar al login sin un botón de logout explícito.
¿Qué es un interceptor HTTP y por qué es necesario?
Aunque el token ya se encuentra en localStorage, ninguna petición lo envía automáticamente al backend. Ahí entra el concepto de interceptor. Un interceptor en Angular captura todas las solicitudes HTTP antes de que salgan, les agrega o modifica headers y luego las despacha [5:16].
Se crea el archivo token-interceptor.ts dentro de la carpeta services:
- La clase
TokenInterceptorService implementa la interfaz HttpInterceptor, lo que obliga a definir el método intercept(request, next) [5:38].
- Dentro del método se extrae el JWT con
localStorage.getItem('jwt').
- Si el token existe, se clona la petición original con
req.clone() y se le añade el header authorization con el valor del token [6:18].
- Finalmente se llama a
next.handle(req) para continuar el flujo de la petición.
¿Cómo se registra el interceptor en la aplicación?
En app.module.ts, dentro del arreglo providers, se agrega un objeto con tres propiedades [7:06]:
provide: apunta a la constante global HTTP_INTERCEPTORS.
useClass: indica la clase TokenInterceptorService.
multi: true: permite que coexistan múltiples interceptores.
¿Cómo resolver el error de CORS con los headers personalizados?
Al probar, aparece un error de CORS (Cross-Origin Resource Sharing) porque el backend en Sails no acepta el header authorization por defecto. La solución está en el archivo de configuración config/security del backend [7:38]:
- Se agrega la propiedad
headers con los valores 'content-type' y 'authorization'.
- Un detalle crítico: la clave debe ser
headers en plural; escribir header en singular no genera un error explícito pero impide que funcione [8:28].
Tras reiniciar el servidor y recargar la aplicación con empty cache and hard reload, las peticiones salen con el header authorization correctamente adjunto y el backend puede identificar al usuario autenticado [8:52].
Con este flujo completo —login, almacenamiento en localStorage, interceptor HTTP y configuración de CORS— la aplicación ya cuenta con un sistema de autenticación funcional. Si te has encontrado con algún detalle adicional al implementar este flujo, comparte tu experiencia en los comentarios.