Introducción

1

Qué necesitas para este curso y qué aprenderás sobre Node.js con Hapi

2

Conceptos principales de hapi y creación de nuestro primer servidor

3

Breve historia y estado actual

Creando un sitio básico con Hapi

4

El objeto h, response y sus herramientas

5

Uso de plugins - Contenido estático

6

Plantillas con Handlebars

7

Renderizado de vistas - Layout y template del home

8

Recibiendo parámetros en una ruta POST - Creación del registro

9

Definir una mejor estructura con buenas prácticas en Hapi

10

Validando la información - Implementando Joi

11

Introducción a Firebase

12

Creando un modelo y guardando en firebase

13

Implementando el login y validación del usuario

14

Autenticación de usuarios - Cookies y estado

15

Manejando errores

16

Visualización de errores

17

Controlar el error 404 en inert y el error de validación

18

Repaso - Creación del modelo y controlador para preguntas

19

Repaso - Creación de las rutas para crear preguntas

20

Listar las últimas preguntas en el home

Aplicacion de conceptos avanzados

21

Enrutamiento avanzado - visualizando una pregunta

22

Enrutamiento avanzado - respondiendo una pregunta

23

Generando la lógica de la plantilla según si es creador o contribuidor

24

Métodos de servidor - respuesta correcta

25

Usando métodos de servidor

26

Manejo del caché - Agregando el home al caché

27

Procesamiento de archivos - Aceptando imágenes

28

Logging con Good - Monitoreando el servidor

29

Creación de plugins - Teoría

30

Creación de plugins - Implementando un API REST

31

Estrategías de autenticación - Asegurando el API REST

32

Seguridad básica - Asegurando el servidor contra CSRF

33

Seguridad básica - Asegurando el servidor contra XSS

Herramientas de desarrollo

34

Depuración del proyecto

35

Ecosistema de Hapi

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Implementando el login y validación del usuario

13/35
Recursos

Teniendo el modelo de Usuario ya definido, podemos pasar a la implementación del Login, para lo cual creamos una nueva vista y agregaremos un método en el controlador, además de las rutas correspondientes para el login y la validación de usuarios.

Al hacer un query sobre los registros almacenados en Firebase, el resultado devuelto es un objeto JSON con los resultados, en los que las keys de cada elemento corresponden con los IDs de cada usuario. Aún cuando el resultado devuelto es sólo un registro, la estructura es la misma.

Es importante tener en cuenta que al recuperar los datos desde Firebase, la contraseña viene cifrada, por lo que la validación debe hacerse comparando ambos datos con bcrypt.

Aportes 10

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Mi aporte en el código

modelo User

  // Metodo de clase para recuperar a un usuario si las credenciales de acceso son correctas
  async validateUser(data) {
    // Ordenar la colección por email, consultar el usuario por su email (no me interesa escuchar cambios en la data, por ello once)
    const queryUser = await this.collection.orderByChild("email").equalTo(data.email).once("value")
    // Obtengo el objeto con los resultados de mi consulta {objId: {}, objId: {}, objId: {}}
    const userFound = queryUser.val()
    if (userFound) {
      // Obtengo un arreglo con los ids de los documentos que forman parte de los resultados de mi busqueda. Me interesa quedarme con el elemento (ObjectId) del primer documento, mas no con el arreglo
      const userId = Object.keys(userFound)[0]
      // comparar si las contraseñas son correctas {documentoResultado.objectId.password}
      const passwordRight = await bcrypt.compare(data.password, userFound[userId].password)

      return (passwordRight) ? userFound[userId] : false;
    }
    return false
  }

Controladores para el login y validación de usuarios

/**
 * Controladores encargados de mostrar la vista de login (formulario)
 * Procesar la data del usuario para verificar que sus credenciales de acceso sean las correctas
 * Leer en la base de datos (Firebase)
 */
function login(req, h) {
  return h.view('login', { title: 'Login' })
}

async function validateUser(req, h) {
  try {
    const userLogin = await user.validateUser(req.payload)
    return userLogin
  } catch (error) {
    console.error(error)
    return h.response('Problemas al logear el usuario').code(500)
  }
}

Rutas

/**
 * Controladores encargados de mostrar la vista de login (formulario)
 * Procesar la data del usuario para verificar que sus credenciales de acceso sean las correctas
 * Leer en la base de datos (Firebase)
 */
function login(req, h) {
  return h.view('login', { title: 'Login' })
}

async function validateUser(req, h) {
  try {
    const userLogin = await user.validateUser(req.payload)
    return userLogin
  } catch (error) {
    console.error(error)
    return h.response('Problemas al logear el usuario').code(500)
  }
}```

@firebase/database: FIREBASE WARNING: Using an unspecified index. Your data will be downloaded and filtered
on the client. Consider adding “.indexOn”: “email” at /users to your security rules for better performance.

Seria bueno revisar esto

si en vez de usar

const userId = Object.keys(userFound)[0]

utilizamos

const [id, info] = Object.entries(userFound)[0];

de esta manera ya tenemos la info del user y el id por separados y nos evitamos de hacer esto

userFound[userId].[CAMPO_QUE_NECESITEMOS]

ya que en este caso info tendría todos los datos el usuario y id seria la llave que nos genera firebase, también podemos hacer esto

const [, info] = Object.entries(userFound)[0];

Así solo tomamos la data del usuario

Hola chicos, he tenido este error y he estado intentando con Joi.object y sigue igual, incluso con type Joi
No sé a qué se deba, precisamente me lo da en el archivo de index.js principal:
server.route(routes)

{ "resource": "/c:/Users/Maided/OneDrive/Escritorio/Platzi/Curso de Node.js con Hapi/index.js", "owner": "typescript", "code": "2345", "severity": 8, "message": "Argument of type '{ [n: number]: { method: string; path: string; handler: (req: any, h: any) => any; } | { path: string; method: string; options: { validate: { payload: ObjectSchema<any>; }; }; handler: (req: any, h: any) => Promise<...>; } | { ...; } | { ...; }; ... 31 more ...; includes(searchElement: { ...; } | ... 2 more ... | { ...' is not assignable to parameter of type 'ServerRoute | ServerRoute[]'.\n Type '{ [n: number]: { method: string; path: string; handler: (req: any, h: any) => any; } | { path: string; method: string; options: { validate: { payload: ObjectSchema<any>; }; }; handler: (req: any, h: any) => Promise<...>; } | { ...; } | { ...; }; ... 31 more ...; includes(searchElement: { ...; } | ... 2 more ... | { ...' is not assignable to type 'ServerRoute[]'.\n The types of 'pop().options' are incompatible between these types.\n Type '{ validate: { payload: Joi.ObjectSchema<any>; }; }' is not assignable to type 'RouteOptions | ((server: Server) => RouteOptions)'.\n The types of 'validate.payload' are incompatible between these types.\n Type 'ObjectSchema<any>' is not assignable to type 'RouteOptionsResponseSchema'.\n Type 'ObjectSchema<any>' is not assignable to type 'SchemaMap'.\n Index signature is missing in type 'ObjectSchema<any>'.", "source": "ts", "startLineNumber": 36, "startColumn": 18, "endLineNumber": 36, "endColumn": 24 }

todo funcionando hasta ahora

Hubiese sido increible, si todo fuera solo un api Rest con Postman o algo parecido…

¯\_(ツ)_/¯

Si a alguien le genera este error:
Error: Cannot set uncompiled validation rules without configuring a validator

En este enlace esta la solución: https://stackoverflow.com/questions/61308370/cannot-set-uncompiled-validation-rules-without-configuring-a-validator

Hasta el momento me ha parecido un curso muy bueno, no se porque hay tan poca participación en el.

Para quienes al hacer la comparación devuelve siempre false:
en la linea donde se realiza la comparación, quitar el await:

const passwordRight = bcrypt.compare(data.password,userFound[userID].password)```