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

Creando un modelo y guardando en firebase

12/35
Recursos

Para implementar el uso de la base de datos de Firebase en nuestro proyecto, crearemos el directorio /config para guardar el archivo json con las credenciales de acceso al servicio, y el directorio /models con los modelos asociados a las diferentes entidades que requiere nuestra aplicaci贸n. Instalamos desde la terminal el m贸dulo firebase-admin con npm. Requerimos el m贸dulo en el index.js del directorio /models e invocamos el m茅todo firebase.initializeApp()

Aportes 18

Preguntas 6

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

Con las nuevas versiones de Hapi tenemos el siguiente error: TypeError: queryData.hasOwnProperty is not a function

Soluci贸n
En el archivo users de la carpeta models

  async create(data) {
    console.log(data)
    // Destructuro el objeto con el payload enviado. Ya que Hapi lo decora con un prototipo null que no es compatible con Firebase
    const user = {
      ...data
    }
    console.log(data)
    user.password = await this.constructor.encrypt(user.password)
    const newUser = this.collection.push(user)
    return newUser.key
  }

Mi aporte en el c贸digo Septiembre 2019

Archivo de conexi贸n a la base de datos

'use strict'

// Informaci贸n de configuraci贸n proporcionada en 
// NombreProyectoFirebase -> configuraci贸n del proyecto -> cuentas del servicio

const firebase = require('firebase-admin')
const serviceAccount = require('../config/firebase.json')

firebase.initializeApp({
  credential: firebase.credential.cert(serviceAccount),
  databaseURL: "https://mxplatzi-overflow.firebaseio.com"
})

// Crear una instancia (referencia) de la base de datos
const db = firebase.database()

// Importar modulos (CLASES) correspondientes a los modelos de la base de datos
const User = require('./users')

// Recordar que los modelos esperan como par谩metro una referencia hacia la base de datos.
// Exportamos las instancias de los modelos listas para ser invocadas en los controladores correspondientes
module.exports = {
  user: new User(db)
}

Archivo de modelo User

'use strict'

const bcrypt = require('bcrypt')

/**
 * Clase compatible con Firebase Data Base
 */

class User {
  // La clase recibe una referencia hacia la base de datos de firebase donde se guardar谩 la informaci贸n
  constructor(db) {
    this.db = db
    this.ref = this.db.ref('/')
    this.collection = this.ref.child('users')
  }

  // M茅todo de clase para guardar un usuario en la base de datos de firebase
  async create(data) {
    console.log(data)
    // Destructuro el objeto con el payload enviado. Ya que Hapi lo decora con un prototipo null que no es compatible con Firebase
    const user = {
      ...data
    }
    // Se genera una contrase帽a encriptada a partir de la proporcionada. this.constructor llama a la clase, ya que el m茅todo encrypt es est谩tico
    user.password = await this.constructor.encrypt(user.password)
    const newUser = this.collection.push(user)
    // Retornamos el id del usuario
    return newUser.key
  }

  // M茅todo est谩tico asincrono para la encriptacion de contrase帽as
  static async encrypt(password) {
    const saltRounds = 10
    const hashedPassword = await bcrypt.hash(password, saltRounds)
    return hashedPassword
  }
}

module.exports = User

Archivo de controlador User

'use strict'

// Definici贸n de controladores de ruta

// Importar el archivo de conexi贸n a la base de datos
const { user } = require('../models/index')

function register(req, h) {
  return h.view('register')
}

/**
 * Controlador encargado de registrar un usuario en la base de datos.
 * La base de datos se encuentra en un servicio desentralizado (Firebase) que retonra una promesa.
 */
async function createUser(req, h) {
  try {
    const createUserId = await user.create(req.payload)
    return h.response(`Usuario registrado satisfactoriamente con el ID ${createUserId}`).code(201)
  } catch (error) {
    console.error(error)
    return h.response('Problemas al registrar el usuario').code(500)
  }
}

module.exports = {
  register,
  createUser
}

El problema de obj.hasOwnProperty se debe a que el objeto de payload tiene una decoraci贸n de prototipo null.

[Object: null prototype] {
  name: 'Fernanda Villar Becerril',
  email: '[email protected]',
  password: 'secreto' }

Esto se soluciona de muchas formas, la mas sencilla es destructurando el objeto.

Si tienen problemas al ejecutar el c贸digo y obtienen:
TypeError: obj.hasOwnProperty
Prueben des estructurando el objeto a la hora de pasarlo como argumento:

const result = await users.create({ ...req.payload })

Recuerden crear en Firebase una > Realtime Database
para que puedan continuar con la clase

Tengo problemas al instalar bcrypt, estoy en win 10 x64 y me dice que la plataforma no est谩 soportada

驴C贸mo hizo el profesor para detener la instalaci贸n de firebase-admin, cuando se le olvid贸 poner -S el final del comando de instalaci贸n de npm? 驴Lo hizo con el equivalente a Ctrl + C en Windows?

Solucion para instalar bcrypt en Windows

https://stackoverflow.com/a/40046466/9053821

PARA PODER INSTALAR BCRYPT EN WINDOWS 10 TUVE QUE EJECUTAR LOS SIGUIENTES PASOS

  1. Instalar las dependencias de node-gyp, as铆:
    Abrimis una consola de comandos normal o de PowerShell con privilegios de Administrador.
npm install --global --production windows-build-tools

Esto Instalar谩 todas las herramientas y configuraciones requeridas

  1. Instalar el paquete de node-gyp, de forma global, con el siguiente comando:
$ npm install -g node-gyp
  1. Instalar el paquete de bcrypt, como dependencia del proyecto, con el siguiente comando:
npm install bcrypt -S

Como se utilizaria con una base de datos relacional como Mysql

para el momento en el que realizo el curso hay un problema con la ultima version de firebase-admin (8.2) y no funcionan los metodos que se ven en la creacion de la clase, o al menos a mi no me sirvio y tuve que usar la version que usan en el curso

Si alguien m谩s usa Windows y tuvo problemas usando bcrypt por x o y raz贸n, en el repo recomiendan utilizar mejor bcryptjs.
鈥淥ptimized bcrypt in JavaScript with zero dependencies. Compatible to the C++ bcrypt binding on node.js and also working in the browser.鈥

Las l铆neas utilzadas en el curso se pueden cambiar por estas:

 static async encrypt(password){
    const salt = 10    
    const hashedPassword = await bcrypt.hash( password, salt)
    return hashedPassword
  
    return hashedPassword
  }

Bye x)

Para los usuarios de Windows deben instalar primero python https://www.python.org/downloads/
Luego correr el siguiente comando en PowerShell como administrador:

npm install --global --production windows-build-tools

Reinicien Win, y luego ejecuten en la terminal:
npm i bcrypt -S

con la version 8.6 de Firebase da problema 鈥渙bj.hasOwnProperty is not a function鈥, tal vez podrian explicar el por que para poder utilizar las librerias en su ultima version, me toco utilizar la que tienen declarada en el packege.json del curso.

Objeto no estructurado

[Object: null prototype] {
  name: 'Juan',
  email: '[email protected]',
  password: '123456'
}

Objeto estructurado

{ name: 'Juan', email: '[email protected]', password: '123456' }

me da este error al tratar de ejecutar npm run dev finalizando el video

@firebase/database: FIREBASE WARNING: {鈥渃ode鈥:鈥渁pp/invalid-credential鈥,鈥渕essage鈥:鈥淐redential implementation provided to initializeApp() via the 鈥渃redential鈥 property failed to fetch a valid Google OAuth2 access token with the following error: 鈥淔ailed to parse access token response: Error: Server responded with status 400.鈥.鈥潁

Si tienen error al instalar firebase-admin de este tipo:

npm ERR! code EPERM

Solo instalen nuevamente npm completamente con esta instruccion:

npm install

y vuelvan a instalar firebase

Me agrada bastante la integraci贸n con typescript ya que te permite incluir tipado escricto y detectar cuando se mutan los objetos y te conviene tener otro acercamiento鈥

as铆 va quedando

import { database } from 'firebase-admin';
import { encrypt } from '../../helpers/encrypter';
import { Users } from '../interfaces/Users';

export class User {
  private db: database.Database;
  private ref: database.Reference;
  private collection: database.Reference;

  constructor(db: database.Database) {
    this.db = db;
    this.ref = this.db.ref('/');
    this.collection = this.ref.child('user');
  }

  async newUser(user: Users) {
    const refUser = this.collection.push();
    const { password, ...data } = user;

    await refUser.set({ ...data, password: await encrypt(password) });

    return refUser.key;
  }
}

y el zip con el avance hasta integrar firebase se los comparto:
zip file

Cualquier feedback bienvenido:
repo github