Aprende a implementar el login con Firebase en Angular con una configuración segura: ajusta las reglas de la base de datos, usa angular/fire y verifica el JSON Web Token en Local Storage. Verás cómo solucionar el error the email address is badly formatted, conectar el formulario con ngModel y confirmar que los datos solo cargan cuando el usuario está autenticado.
¿Cómo activar login con Firebase y proteger lectura y escritura?
Configurar las reglas de seguridad es clave. Al inicio, lectura y escritura estaban en true, lo que permite acceso público. La mejora es exigir autenticación con la condición auth != null y publicar los cambios.
Un detalle importante: después de registrar, la librería angular/fire deja al usuario logueado automáticamente. Esto explica por qué, tras aplicar reglas, los datos aún se ven: existe una sesión activa en el navegador.
¿Dónde se guarda la sesión en el navegador?
En Chrome, la sesión se observa en Application > Local Storage > localhost bajo la clave Firebase Auth User. Ese objeto guarda el JSON Web Token, que se usa para autenticar solicitudes.
Eliminar esa clave provoca que falle la carga de datos.
Angular intenta recargar la lista y se muestra el error capturado en el módulo de HTTP.
Al refrescar, sin sesión, ya no se listan los lugares, como dictan las reglas.
¿Por qué apareció el error con el email y cómo se corrige?
Al intentar el primer login, surge el mensaje: the email address is badly formatted. No se debía a un correo mal escrito, sino a que se estaban enviando parámetros fijos en lugar de enlazar el formulario.
El template no tenía ngModel en los inputs.
El componente enviaba email y password hardcodeados.
Solución: replicar el patrón usado en registro, moviendo a un objeto de parámetros y enlazando con ngModel.
¿Qué cambios hacer en login.component y en el servicio?
En el HTML, enlazar inputs y enviar el objeto al hacer clic:
En autorizacion.service, cambiar createUserWithEmailAndPassword por signInWithEmailAndPassword y ajustar el mensaje:
login(email:string, password:string){returnthis.afAuth.signInWithEmailAndPassword(email, password).then(()=>alert('usuario logueado con éxito')).catch(err =>alert('un error ha ocurrido: '+ err.message));}
Con estos cambios, al hacer login:
Se agrega de nuevo la clave de auth en Local Storage.
El token queda disponible para autenticar peticiones.
En inicio, la lista de lugares vuelve a cargar porque el usuario ya está autenticado.
¿Qué validar después del login para una mejor experiencia?
Una vez que el login funciona y las reglas protegen el acceso, aún es posible navegar por pantallas no restringidas sin estar autenticado. El siguiente paso recomendado es la protección de rutas para ocultar secciones y menú cuando no hay sesión activa.
Asegurar rutas sensibles con guardas de autenticación.
Ocultar elementos del menú que requieren sesión.
Mostrar estados claros: logueado o no logueado.
¿Quieres que profundicemos en la protección de rutas con Angular y Firebase? Deja tus dudas o comentarios y contemos qué parte te gustaría ver implementada paso a paso.
Esta fue la opción más rápida y eficaz, muchas gracias.
Hola, para quienes no saben como obtener la Key del Local Storage y poder desplegar los lugares una vez logueados:
Hola @vjolvera, nuevamente en modo: “Héroe sin capa”:
Resulta que SI sé como obtener la famosa KEY que muy amablemente citaron los compañeros PERO no dieron detalle de ello, así que pues compartiré una captura de pantalla desde mi editor para que se aprecie correctamente el procedimiento para obtener esta Key desde la ventana de depuración o inspección en Chrome:
Para quienes somos usuarios de Windows pulsamos la combinación de teclas: “Ctrl+ Shift + i” y automáticamente se desplegará la ventana de inspección de elementos de Chrome “Developer Tools”.
Una vez tengamos la ventana “Developer Tools”, seguir estos pasos:
Identificar la pestaña “Application”
Una vez seleccionada la pestaña “Application”, desde el costado izquierdo de la ventana de herramientas de desarrollador, se despliega desde la sección “Storage”, el item “Local Storage”.
Una vez seleccionado este item, se procede a seleccionar su nodo Hijo directo y justo al costado superior derecho de la ventana, aparecerá una columna cuyo titulo es: “Key”, seguido de otra columna: “Value”.
Basta entonces con seleccionar el item o elemento que encontrarán justo debajo del item “currentUser”, y presionar doble click sobre este “en mi caso, es exactamente el segundo elemento”, dando doble click se activa el modo de editar, entonces copiamos toda la selección y lo pegamos en un editor para dejarlo pendiente y aplicar la otra parte del procedimiento. Una captura de pantalla en resumen de estos primeros 3 pasos se ve así:
Una vez tengamos en memoria toda esta <key> que de hecho es algo extensa, se procede a abrir el fichero “lugares.service.ts” y justo acá empalmamos con la solución propuesta por: @andresfelipechaparro
La captura de pantalla de como tengo este bloque de código que retorna los lugares mediante HTTP:
Espero aportar algo a la comunidad y que no nos estanquemos. Siempre hay que resolver errores sobre la marcha y eso define nuestra esencia. Saludos.
La diferencia entre el video y el codigo que tenemos es que nosoros cargamos las tablas por medio de servicios get, a Eduardo le funciona porque el esta utilizando sockets por lo que las funcionas detecan automaticamente el logueo, varios compañeros comentaro ya como hacerlo por medio de servicios, pero para seguir el curso sin problemas, seria cuestion de no usar los ajustes en servicios get y post
Al igual que muchos, me encontré con el mismo problema de la autenticación usando servicios rest [HTTP], esta claro que con socket funciona facilmente, pero la idea es hacer el ejercicio con servicios rest.
Les comparto la solución que implemente:
Basado en la documentación de firebase Autentica solicitudes de REST en la sección "Autentica con un token de ID
"
En el servicio lugares.service.ts, agregamos un parametro a la URL
Ahora desde el método que consume el servicio el idToken del
angularFireAuth.auth.currentUser.getIdToken
Excelemte aporte, para que que el codigo de @afvalenciab funcione, es necesario previamente estar logeados, de lo contrario la consola arrojara un error como este “TypeError: Cannot read property ‘getIdToken’ of null”, por otro lado, no olviden importar “import { AngularFireAuth } from “angularfire2/auth/auth””…Saludos;
Voy perdido, sigo los consejos de los compañeros, pero no hay caso, no me puedo autenticar para recuperar los datos, a pesar de estar autenticado y haber pasado el token.
Si esta petición de los lugares, la hecemos por https, pero los ejemplos del profe son en sockets, como hacerlo en sockets.
Bueno estoy desanimado... a ver si me salgo.
Me funcionó todo con Angular 8, lo único que tuve que cambiar es en la función de getLocations o obtenerLugares, como lo tengan configurado, hay que obtenerlo por medio de sockets y comentar el otro código. Te compartó lo que hice en el código.
Pero si el usuario ya existia por medio del signup o registro, no deberia mandar un error de todas formas ? y poner una condicion en el login de que si este usuario ya existe envie un mensaje diciendo ‘‘This email is already taken’’ por ejeplo. ?
Es un riesgo de seguridad decir que un email ya existe, con esto pueden hacer ataques ya que tu le dices al atacante que un usuario existe o no, siempre debes decir por ejemplo que la combinación de usuario y contraseña no existe, con esto no saben si es que es un error en la contraseña o un error que el usuario no existe.
Bueno por lo visto, en la última versión , Firebase, el KEY y resto de datos, de la auth ya no están en local storage, lo ha puesto en IndexDB, por lo que se tendría que modificar las soluciones de los compañeros, y el vídeo queda muy desactualizado, ya que hasta la configuración de firebase ha cambiado.
Las reglas de permisos a la database desde firebase, quedarían así
service cloud.firestore{ match /databases/{database}/documents { match /{documents=**}{ allow read,write:if request.auth.uid!=null;}}}
Esto es para todos los documentos, y creamos un regla para un solo documento
service cloud.firestore{ match /databases/{database}/documents { match /{lugares}{ allow read,write:if request.auth.uid!=null;}}}
tengo un problema al momento de login al parecer si se hace correctamente ya que me da la info con response pero no se asing el json web token que debo hacer
Sin ver tu código es difícil saber que esta fallando o que puede estar pasando, puede ser un error de digitación y estés guardando la info en otra variable o algo por el estilo.
gracias no se por que pero no se me asigna en local storage se asigna en la parte de indexDB
pero ya lo selvente era por que mantenia con get la peticion de lugares creo
Tengo un problema, puedo loguearme y registrarme sin problemas, ahora, tengo un componente que registra usuarios, pero cuando registro un usuario reemplaza al usuario logueado (se reemplaza todo el firebaseAuthUser), por que pasa esto?, solo quiero que lo registre no que reemplaze a mi usuario logueado.