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

A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

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? Crea una cuenta o inicia sesi贸n.

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鈥: 鈥渆mail鈥 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)```