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

Validando la informaci贸n - Implementando Joi

10/35
Recursos

La validaci贸n de los datos suministrados por el usuario puede hacerse tanto en el frontend como en el backend, incluso puede hacerse en ambos lados, lo cual se recomienda.

Para hacer la validaci贸n de informaci贸n en el backend, Hapi cuenta con un m贸dulo llamado Joi que ofrece m煤ltiples condiciones de validaci贸n, como: tipo de dato, m铆nimos y m谩ximos, condiciones personalizadas, etc.

Joi nos permite generar validaci贸n de un esquema espec铆fico en Hapi en el mismo momento en que se definen las rutas.

Luego de instalar y requerir el m贸dulo en el arhivo routes.js ser谩 necesario agregar la propiedad options que contiene a su vez validate y luego payload, en esta caso porque los datos ser谩n recibidos por POST, all铆 definimos entonces las condiciones de validaci贸n para cada dato esperado.

Aportes 16

Preguntas 2

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Ojo el esquema de validaci贸n actual para el payload es bajo un joi object

        {
            method: 'POST',
            options: {
                validate: {
                    payload: joi.object({
                        name: joi.string().required().min(3),
                        email: joi.string().email().required(),
                        password: joi.string().required().min(6)
                    })
                }
            },
            path: '/create-user',
            handler: user.createUser
        }

Mi aporte en el c贸digo
Al d铆a de hoy es importante instalar hapi, sus m贸dulos y plugins desde

npm i @hapi/hapi @hapi/inert @hapi/joi @hapi/vision

Por otra parte, es posible que en la versi贸n de hapi 18.4 y joi 16.1.4 no funcione la validaci贸n tal como lo explica el profesor. Dejo un ejemplo completo actualizado hasta Septiembre 2019

// Requerir m贸dulo para validaci贸n de datos en el backend
const Joi = require('@hapi/joi')

// Requerir modulos de controlador de ruta
const siteController = require('./controllers/site')
const userController = require('./controllers/user')

// Declarar conjunto de rutas y asociar su respectivo controlador de ruta
const routes = [
  {
    method: 'GET',
    path: '/',
    handler: siteController.index
  },
  {
    method: 'GET',
    path: '/register',
    handler: userController.register
  },
  {
    // Los datos enviados a esta ruta deben cumplir con cierto esquema de validaci贸n. 峁攁ra ello se agrega dentro de sus opciones la validaci贸n del payload (body request)
    // Cada esquema define los criterios que debe cumplir un campo para pasar la validaci贸n 
    method: 'POST',
    path: '/create-user',
    handler: userController.createUser,
    options: {
      validate: {
        payload: Joi.object({
          email: Joi.string().email().required(),
          name: Joi.string().required().min(3),
          password: Joi.string().required().min(6)
        })
      }
    }
  },
  {
    // Ruta para servir archivos est谩ticos asociados (img/css/js)
    method: 'GET',
    path: '/{param*}',
    handler: {
      directory: {
        path: '.',
        redirectToSlash: true
      }
    }
  }
];

module.exports = routes

Si les aparece un error como el siguiente:

Error: Cannot set uncompiled validation rules without configuring a validator

Deben de definir el payload como un Joi.Object

   options: {
      validate: {
        payload: Joi.object({
          name: Joi.string()
            .required()
            .min(3),
          email: Joi.string()
            .email()
            .required(),
          password: Joi.string()
            .required()
            .min(6)
        })
      }
    },

Estoy impresionado con la facilidad de conectar el backend con el frontend

https://www.npmjs.com/package/joi ya fue deprecado, para el curso si funciona, pero para hacer una aplicaci贸n ya deber铆an de usar el actualizado. Ahora esta en https://github.com/hapijs/joi

Buenas tardes, que plugin utilizan en el browser para que la respuesta se muestre en una forma grafica amigable??

En mi browser se presenta asi鈥 **{鈥渟tatusCode鈥:400,鈥渆rror鈥:鈥淏ad Request鈥,鈥渕essage鈥:鈥淚nvalid request payload input鈥潁

Si llegan a tener un error como este

Lo que deben hacer es agregar en index.js, un required para tener a Joi en dicho archivo, y requerirlo como una propiedad dentro del configurador de server.

   const Hapi = require('@hapi/hapi')
const handlebars = require('handlebars')
const inert = require('@hapi/inert')
const vision = require('@hapi/vision')
const path = require('path')
const routes = require('./routes')
const Joi = require('joi')

const server = Hapi.server({
  port: process.env.PORT || 8080,
  host: 'localhost',
  routes: {
    files: {
      relativeTo: path.join(__dirname, 'public')
    }
  }
})

async function init () {
  try {
    await server.register(inert)
    await server.register(vision)

    server.views({
      engines: {
        hbs: handlebars
      },
      relativeTo: __dirname,
      path: 'views',
      layout: true,
      layoutPath: 'views/layout'
    })
    server.validator(Joi)
    server.route(routes)

    await server.start()
  } catch (error) {
    console.error(error)
    process.exit(1)
  }

  console.log(`Servidor lanzado en: ${server.info.uri}`)
}

me sale este error
AssertionError [ERR_ASSERTION]: Invalid schema content:
at Object.exports.schema (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\cast.js:55:10)
at internals.Object.keys (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\types\object\index.js:358:35)
at Object.exports.schema (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\cast.js:36:29)
at internals.Object.keys (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\types\object\index.js:358:35)
at Object.exports.schema (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\cast.js:36:29)
at internals.Object.keys (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\types\object\index.js:358:35)
at Object.exports.schema (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\cast.js:36:29)
at module.exports.internals.Any.root.compile (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\node_modules\joi\lib\index.js:159:25)
at Object.exports.compile (C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\lib\validation.js:21:49)
at C:\Users\Gloria Lopez\gloria\cursos\carreraBackend_JS\hapi\platzi-overFlow\node_modules\Hapi\lib\route.js:195:43 {
generatedMessage: false,
code: 鈥楨RR_ASSERTION鈥,
actual: false,
expected: true,
operator: 鈥==鈥,
path: 鈥榥ame.$_root.alternatives鈥
}

En este momento ya hubo actualizaciones a @hapi por lo que la importaci贸n del modulo joi ser铆a:

const Joi = require('joi');

Para la implementaci贸n que estoy haciendo con typescript, pug y utilizando es6 modules:

import Joi from 'joi';

El zip de la implementaci贸n del proyecto lo encuentran en:
archivo zip

y cualquier feedback al repo es bienvenida:
repo github

Si tienen un error con joi, de este tipo:

AssertionError [ERR_ASSERTION]: Invalid schema content:                                                                                                                      
    at Object.exports.schema (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\node_mod
ules\joi\lib\cast.js:55:10)                                                                                                                                                  
    at internals.Object.keys (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\node_mod
ules\joi\lib\types\object\index.js:358:35)                                                                                                                                   
    at Object.exports.schema (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\node_mod
ules\joi\lib\cast.js:36:29)                                                                                                                                                  
    at internals.Object.keys (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\node_mod
ules\joi\lib\types\object\index.js:358:35)                                                                                                                                   
    at Object.exports.schema (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\node_mod
ules\joi\lib\cast.js:36:29)                                                                                                                                                  
    at module.exports.internals.Any.root.compile (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_m
odules\hapi\node_modules\joi\lib\index.js:159:25)                                                                                                                            
    at Object.exports.compile (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\lib\val
idation.js:21:49)                                                                                                                                                            
    at E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\node_modules\hapi\lib\route.js:195:43            
    at Array.forEach (<anonymous>)                                                                                                                                           
    at module.exports.internals.Route._setupValidation (E:\Documents\03 Cursos y Universidad\01 Platzi\00 Platzi Master\learning path\02 Curso Node con Hapi\platzi-overflow\
node_modules\hapi\lib\route.js:193:60) {                                                                                                                                     
  generatedMessage: false,                                                                                                                                                   
  code: 'ERR_ASSERTION',                                                                                                                                                     
  actual: false,                                                                                                                                                             
  expected: true,                                                                                                                                                            
  operator: '==',                                                                                                                                                            
  path: '$_root.alternatives'                                                                                                                                                
}                                                                                                                                                                            
[nodemon] app crashed - waiting for file changes before starting...                                                                                                          

Se soluciona instalando:

npm install @hapi/hapi

instalen

npm i @hapi/joi

ya que el paquete que usan en el surso ya fue deprecado

npm i joi -S

Realize la clase con los nombres normales de los modulos sin @hapi/ y funcionaron perfecto solo hay que colocar al payload el joi.object cabe aclarar que trabaje en linux

    {
        method: 'POST',
        options: {
            validate: {
                payload: {
                    name: Joi.string().required().min(3),
                    email: Joi.string().email().required(),
                    password: Joi.string().required().min(6)
                }
            }
        },
        path: '/create-user',
        handler: user.createUser
    } ,

Muchas gracias por la explicaci贸n de esta extensi贸n instructor Adrian, funciona mientras se sigan los pasos y tambi茅n se a帽ada el Joi.object despu茅s del payload.