0% encontró este documento útil (0 votos)
86 vistas29 páginas

Node - Js Udemy

Este documento describe los pasos para configurar un proyecto Node.js utilizando Express. Inicialmente se instala Node.js y se crea un archivo package.json. Luego se instalan las dependencias como Express y nodemon. Finalmente, se crea un servidor Express en el archivo principal index.js utilizando routing para diferentes rutas HTTP.

Cargado por

Otto Szarata
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
86 vistas29 páginas

Node - Js Udemy

Este documento describe los pasos para configurar un proyecto Node.js utilizando Express. Inicialmente se instala Node.js y se crea un archivo package.json. Luego se instalan las dependencias como Express y nodemon. Finalmente, se crea un servidor Express en el archivo principal index.js utilizando routing para diferentes rutas HTTP.

Cargado por

Otto Szarata
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 29

Proyecto Bienes y Raices

- Instalar Node.js descargándolo desde la página web


- Iniciar proyecto desde Visual Studio Code dentro de la carpeta del proyecto
- Crear nuestro archivo package.json desde la terminal:
o node init
o Este almacenara los datos de nuestro proyecto como:
 Nombre
 Versión
 Descripción
 Main
 Scripts
 Keywords
 Autor
 Licencia
 Dependencias
- {
-   "name": "bienesraices_mvc",
-   "version": "1.0.0",
-   "description": "Proyecto de bienes y raices",
-   "main": "index.js",
-   "scripts": {
-     "test": "echo \"Error: no test specified\" && exit 1"
-   },
-   "keywords": [
-     "MVC",
-     "Pug",
-     "Tailwind",
-     "MySQL",
-     "Sequelize"
-   ],
-   "author": "[email protected]",
-   "license": "ISC",
-   "dependencies": {
-     "express": "^4.18.1"
-   }
- }

- Instalar dependencias:
o Existen dos tipos de dependencias:
 Dependencias de desarrollo: que solo usas mientras desarrollas el
proyecto. Ejemplo:
 MySQL o gestor local de bases de datos
 Dependencias que requiere el proyecto para funcionar correctamente.
Ejemplo:
 Un sistema de pagos dentro de la aplicación.
o Instalar Express:
 npm install express
 Se nos creara una carpeta llamada node_modules, que es donde
estarán las librerias y dependencias que instalamos.
 Y nuestro package-json que es donde veremos las dependencias
de las dependencias del proyecto.
 En el archivo package.json borramos todo “dependencies”
- "dependencies": {
-     "express": "^4.18.1"
-   }
o
 Para instalar dependencias:
o npm i -D express
- "devDependencies": {
-     "express": "^4.18.1"
-   }
o Hace que el hosting ignore esas dependencias para que no
las instale automáticamente
o Pero en este caso express es una dependencia normal por
lo que regresamos a instalarlo normalmente.
o Para instalarlo nuevamente normal:
 npm install express
- Como llamar el código de Node.js
o Crear archivo principal que es el que debes correr, ejemplo: main.js, app.js,
node.js, index.js etc…(incluso puede ser el nombre del proyecto).
o En el archivo package.json están los scripts los cuales son los que podemos
mandar a llamar.
o Por default el archivo estará asi
- "scripts": {
-     "test": "echo \"Error: no test specified\" && exit 1"
-   },
o Pero podemos cambiarlo asi por ejemplo para que corra nuestro archivo principal
- "scripts": {
-     "start": "node ./index.js"
-   },
o Para mandar a llamar nuestro script:
 npm run start
 PS C:\Users\szott\Dropbox\Desarrollo\bienesraices_mvc> npm
run start

 > [email protected] start
 > node ./index.js

 hola mundo
 al ver esto vemos que corre nuestro archivo principal
 Tambien podemos llamarlo sin la palabra clave “run”
 npm start

- Como Hacer para no estar llamando ese npm start (Instalar Nodemon)
o Instalar la dependencia
 npm i -D nodemon
 nos instalara el paquete:
- "devDependencies": {
-     "nodemon": "^2.0.20"
-   }
 Para usar este script devemos agregarlo en el package.json en el apartado
de scripts:
- "scripts": {
-     "start": "node ./index.js",
-     "server": "nodemon index.js"
-   },
 Y para correrlo ya solo ponemos en terminar
o npm run server
 PS C:\Users\szott\Dropbox\Desarrollo\
bienesraices_mvc> npm run server

 > [email protected] server
 > nodemon index.js

 [nodemon] 2.0.20
 [nodemon] to restart at any time, enter `rs`
 [nodemon] watching path(s): *.*
 [nodemon] watching extensions: js,mjs,json
 [nodemon] starting `node index.js`
 hola mundo
 7
 [nodemon] clean exit - waiting for changes before
restart
o Y con eso inicializamos nuestro servidor

- Crear servidor con express:


o Debemos importar Express a nuestro archivo principal en este caso index.js:
 Versión anterior (CommonJS):
- const express = require('express');
-
- //crear la app
- const app = express();
-
- //routing
- app.get('/', function(req, res) {
-     res.send('Hola mundo');
- })
-
- //Definir un puerto y arrancar el proyecto
- const port = 3000;
-
- app.listen(port, () => {
-     console.log(`El servidor esta funcionando en el puerto ${port}`);
- })
 app tendrá todos los valores de express.
 Si lo corremos vemos que nos inicializa el servidor
o PS C:\Users\szott\Dropbox\Desarrollo\bienesraices_mvc>
npm run server
o
o > [email protected] server
o > nodemon index.js
o
o [nodemon] 2.0.20
o [nodemon] to restart at any time, enter `rs`
o [nodemon] watching path(s): *.*
o [nodemon] watching extensions: js,mjs,json
o [nodemon] starting `node index.js`
o El servidor esta funcionando en el puerto 3000
 Si lo corremos en el navegador:
o localhost:3000
o Nos aparecerá hola mundo el routing nos envia hacia allí
o El routing soporta los comandos (get, post, delete, etc…)
- //routing
- app.get('/', function(req, res) {
-     res.send('Hola mundo');
- })
 Version Actual (ECMAScript):
 Ya no se usa llamar la librería con “require”
 Ahora debemos habilitar ECMAScript
 Debemos abrir package.json:
o En cualquier lugar debemos definir el “type”
-   "type": "module",
 Entonces ya no debemos llamar a express con un “Require” ahora
debemos escribirlo asi:
- import express from 'express'
- Routing y métodos HTTP:
o Que es el routing?
 El routing es por donde van a transitar los usuarios de nuestro sitio web o
aplicación.
 Con diferentes Rutas, nuestros usuarios podrán navegar a lo largo de
diferentes secciones del sitio web o llenar diferentes formularios.
o Metodos HTTP:
 Get: Utilizados para mostrar información
 Post: Utilizado para enviar información
 Put/Patch: utilizado para actualizar información.
 Delete: para eliminar información.
o Express ya soporta Routing y los diferentes métodos HTTP y puedes utilizarlos para
web o móvil.
o Debemos crear una carpeta para Routing donde van a estar ordenadas de una
mejor manera todas nuestras rutas:
 Crear carpeta llamada “routes”
 Y dentro de la carpeta crear archivo por cada modulo que creemos.
Ejemplo:
 routes->usuarioRoutes.js
 Aquí crearemos todas las rutas de autenticación de usuario
 En ese archivo debemos importar también express y crear una
variable para router
 Luego podemos crear todas nuestras rutas
 Y por ultimo debemos exportarlo para poder utilizarlo en otros
lugares
 Ejemplo: archivo usuariosRouters.js
- //importamos express
- import express from "express";
- //definimos router
- const router = express.Router();
-
- //routing
- router.get('/', function(req, res) {
-     res.send('Hola mundo');
- });
-
- router.get('/nosotros', function(req, res) {
-     res.send('Informacion de nosotros');
- });
-
- //exportamos router
- export default router
 luego podemos importar usuarioRoutes.js a los archivos en que lo
necesitemos
 Ejemplo: index.js
- //importamos express
- import express from 'express'
- //importamos usuariosRoutes.js
- import usuariosRoutes from './routes/usuarioRoutes.js';
-
- //crear la app
- const app = express();
-
- //routing
- app.get('/', usuariosRoutes);
- app.get('/nosotros', usuariosRoutes);
-
- //Definir un puerto y arrancar el proyecto
- const port = 3000;
-
- app.listen(port, () => {
-     console.log(`El servidor esta funcionando en el puerto ${port}`);
- })
 Ya podemos llamar a nuestras rutas de usuario desde index solo
con el nombre del modulo de usuariosRoutes.
 Para evitar llamar cada ruta de usuariosRoutes podemos llamarla
con la función “use” en ves de get, post, etc…
 Ejemplo:
- //routing
- app.use('/', usuariosRoutes);
 de esta manera llamamos a todas las rutas de usuarioRoutes.js
que empiecen con ‘/’.
o Routing en Express:
 Postman:
 Descargamos Postman desde su pagina web
 Lo instalamos
 Otra opción en Thunder Client que se puede descargar desde
visual studio code.
 Nos permite comprobar todas nuestras rutas y su resultado solo
poniendo nuestra url: http://localhost:3000/
 Debemos poner que tipo de petición es.(Get, Post, etc.)
 Podemos usar también route para englobar peticiones con la
misma ruta ejemplo:
- router.route('/')
-     .get(function(req, res) {
-         res.send('Hola mundo en express');
-     })
-     .post(function(req, res) {
-         res.json({msg: 'Respuesta de tipo Post'});
-     })
 En ves de verlas por separado:
- router.get('/', function(req, res) {
-     res.send('Hola mundo en express');
- });
-
- router.post('/', function(req, res) {
-     res.json({msg: 'Respuesta de tipo Post'});
- });

- Template engines:

o Que es un template engine?


 O motores de plantilla son tecnologías que nos permiten crear el código
HTML y mostrar información contenida en variables de una forma mas
compacta.
 En Node.js Pug, Handlebars, EJS son las opciones mas populares.
 También es posible utilizar React, Angular, Svelte o Vue como tu Template
Engine; pero necesitaras crear un api con respuestas JSON.
o Ventajas de un Template Engine:
 La forma en que se crea el código HTML tiende a ser más simple.
 Puedes utilizar e imprimir información del servidor o base de datos de una
forma más sencilla.
 La seguridad es mas sencilla de implementar y que la información es
renderizada por el mismo servidor.
o Desventajas de un Template Engine:
 Cuando mostramos información con un template engine, esta información
y sus interacciones no son muy dinámicas a compoaracion de React o Vue.
 Consumen mas recursos ya que el código HTML es creado por el servidor a
diferencia de Vue o React donde es creado por el cliente(navegador).

- Implementar Pug como Template engine:


 Instalar desde la terminal:
 npm i pug
 Ya instalado nos vamos a nuestro archivo principal en este caso
index.js y habilitamos pug:
- //habilitar Pub
- app.set('view engine', 'pug');
- app.set('views', './views');
 debemos crear una carpeta donde van a estar todas nuestras
vistas en este caso se llama views, además dentro de esta carpeta
se crearan carpetas para las vistas de cada modulo, ejemplo: la
carpeta views->auth->login.pug
 las vistas tienen que tener el tipo de archivo .pug
 debemos de rutear en index.js nuestros modulos por ejemplo
para usuariosRoutes.js de la raíz y escribimos la carpeta de auth,
ya no ponemos la carpeta views, porque ya lo definimos en la
habilitación de Pug:
- //routing
- app.use('/auth', usuariosRoutes);
 llamar la vista en el modulo:
- router.get('/login', function(req, res) {
-     res.render('auth/login');
- });
 Login.pug es código html pero solo la inicial de cada etiqueta
identada para saber que etiqueta es padre de la otra Ejemplo:
- div
-     h2 Login
-     p Inicia Sesion:
 Esto seria igual a:
- <div>
-     <h2>Login</h2>
-     <p>Inicia Sesion</p>
- </div>
 Para utilizar clases en las etiquetas en pug:
-    h2(class="center") Login
 O:
-    h2.text-center Login
 Pasar información a la vista:
- router.get('/login', function(req, res) {
-     res.render('auth/login', {
-         autenticado: true
-     });
- });
 Además de mandar la vista, como segundo parámetro le pasamos la
información.
 Al cargar la vista en este caso:
- div
-     if autenticado
-         p Usuario Autenticado
-     else    
-         p Inicia Sesion:
 Podemos ver que auntenticado es true por lo cual nos mostrara en el
navegador
 Usuario Autenticado
 Si es False nos mostrara: Iniciar Sesion:

- MVC (Modelo, Vista, Controlador):


o Que es mvc?
 MVC son las iniciales de Modelo Vista Controlador.
 Es un patrón de arquitectura de software que permite la separación de
obligaciones de cada pieza de tu código.
 Enfatiza la separación de la lógica de programación con la presentación.
o Ventajas de MVC:
 MVC no mejora el performance del código, tampoco da seguridad; pero tu
código tendrá un mejor orden y será fácil de mantener.
 En un grupo de trabajo, el tener el código ordenado permite que mas de
una persona pueda entender que es lo que hace cada parte de él.
 Aprender MVC, hará que otras tecnologías como Laravel, Nest, Rails,
Django, Net Core, Spring Boot te sean más sencillas de aprender.
o Partes de MVC:
 M= Modelo:
 Encargado de todas las interacciones en la base de datos, obtener
datos, actualizarlos y eliminar.
 El modelo se encarga de consultar una base de datos, obtiene la
información pero no la muestra, eso es trabajo de la vista.
 El modelo tampoco se encarga de actualizar la información
directamente, es el Controlador quien decide cuando llamarlo.
 V= Vista
 Se encarga de todo lo que se vie en pantalla (HTML)
 Node soporta múltiples Template Engine como son EJS, Pug,
Hadlebars.
 Si utilizas React, Vue, Angular, Svelte, estos serian tu vista.
 El modelo consulta la base de datos, pero es por medio del
controlador que se decide que Vista hay que llamar y que datos
presentar.
 C= Controlador
 Es el que comunica modelo y vista; antes de que el Modelo
consulte la base de datos el Controlador es el encargado de llamar
un Modelo en especifico.
 Una ves consultado el Modelo, el controlador recibe esa
información, manda a llamar a la vista y le pasa la información.
 El controlador es el que manda a llamar la vista y modelos, que se
requieren en cada parte de tu aplicación.
o Router en MVC:
 Es el encargado de registrar todas las URL’s o Endpoints qu va a soportar
nuestra aplicación.
 Ejemplo: Si el usuario accede a /clientes el router ya tiene registrada esa
ruta y un controlador con una función que sabe que Modelo debe llamar y
que vista mostrar cuando el usuario visita esa URL.

- Implementando Controllers:
o Vamos a crear una carpeta en la raíz llamada controllers
o En esta carpeta iran todos los controladores para cada modulo que creemos
o En este caso el controlador se llamara usuarioController.js
o Creamos el archivo usuarioController.js dentro de la carpeta
 Controllers->usuarioController.js
o usuarioController: pondremos todas nuestras funciones y las exportamos
o ejemplo:
- const formularioLogin = (req, res) => {
-     res.render('auth/login', {
-         autenticado: false
-     })
- }
-
- export {
-     formularioLogin
- }
o Luego debemos importarla en index.js y llamarlas
- //importamos express
- import express from "express";
-
- //importamos formularioLogin
- import { formularioLogin } from "../controllers/usuarioController.js";
-
- //definimos router
- const router = express.Router();
-
- router.get('/login', formularioLogin);
-
- //exportamos router
- export default router

- Implementar CSS a nuestro Proyecto:

o Tailwindcss:
 Para instalar debemos escribier en la terminal:
npm i -D tailwindcss autoprefixer postcss postcss-cli
-D porque solo será una dependencia de desarrollo
En nuestro package.json veremos las devDependencies y tenemos
que tener instaladas las 4 que escribimos en terminal:
-  "devDependencies": {
-     "autoprefixer": "^10.4.12",
-     "nodemon": "^2.0.20",
-     "postcss": "^8.4.16",
-     "postcss-cli": "^10.0.0",
-     "tailwindcss": "^3.1.8"
-   }
 En el archivo principal debemos decile a Node.js donde están los
archivos estáticos, en que parte va a encontrar las imágenes, css
etc.
 En este caso creamos la carpeta public
- //carpeta publica
- app.use( express.static('public'));
 en esta carpeta public Podemos tener todos los archivos estáticos
como css, imágenes, archivos JavaScript, etc.
 Podemos crear dentro de la carpeta public carpetas para cada una
de ellas, ejemplo
o public/css
o public/img
o public/js
o etc…
 Crear archivo tailwind.css
 En la carpeta css creamos el archivo tailwind.css
 Debemos llamar los componentes de tailwind dentro de este
archivo css Ejemplo:
- @tailwind base;
- @tailwind components;
- @tailwind utilities;
 En terminal también debemos iniciar tailwindcss escribimos:
o npx tailwindcss init -p
 nos creara dos archivos
 postcss.config.cjs
 tailwind.config.cjs
o En archivo tailwind.config.cjs debemos:
 Decirle en que carpeta o archivos esta el archivo
css
 Por defecto lo veremos asi:
- /** @type {import('tailwindcss').Config} */
- module.exports = {
-   content: [],
-   theme: {
-     extend: {},
-   },
-   plugins: [],
- }

En content vamos a escribir donde están esas
vistas:
-   content: ['./views/**/*.pug'],
 Podríamos hacer una línea por vista pero al
agregar los asteriscos (*) le decimos que en la
carpeta views cualquier archivo con
terminación .pug
o Luego debemos compilar tailwind
 En el archivo package.json debemos agregar un
script:
- "scripts": {
-     "start": "node ./index.js",
-     "server": "nodemon index.js",
-     "css": "postcss public/css/tailwind.css -o public/css/app.css"
-   },
 Luego comprobamos compilando en la terminal:
 npm run css
 y si tenemos clases que hemos usado en
nuestras vistas .pug, veremos en el
archivo public/css/app.css que nos a
agregado las clases que hemos utilizado.
 Este comando en terminal debemos
correrlo cada ves que agreguemos una
clase en nuestros .pug.
 Agregar –watch a app.ccs para que se actualice
automáticamente:
- "css": "postcss public/css/tailwind.css -o public/css/app.css --watch"

- ORM (bases de datos):

o ORM son las iniciales de Object Relational Mapping


o Es una técnica que se utiliza donde los datos de una base de datos son tratados
como Objetos, utilizando un paradigma de Programación Orientada a Objetos
o Node.js tiene una gran cantidad de ORM’s que se instalan como librería
o En MVC; un ORM se relaciona bastante con el Modelo
o Ventajas de un ORM:
 Comenzar a crear aplicaciones que utilicen bases de datos, sin necesidad
de escribir código SQL y tampoco saber sobre modelado de bases de
datos.
 Velocidad en desarrollo ya que tienen una gran cantidad de métodos para
crear, listar, actualizar o eliminar datos.
 La mayoría cuentan con todas las medidas de seguridad.
o Ejemplo de código ORM:
 En SQL: INSERT INTO ‘categoria’(‘nombre’)VALUES(‘Casa’)
 ORM: Categoria.create({ nombre: ‘Casa’})
o Algunos ORM:
 Prisma
 Mongoose
 TypeORM
 Sequelize
 Bookshelf.js
o Conectando Bases de datos usando SEQUELIZE en Node.js:
 Instalar Sequelize y mysql 2:
 En la terminal:
o npm i sequelize mysql 2
 Crear base de datos en PhpMyAdmin
 Crear una carpeta en proyecto llamada “config”
 Dentro un archivo llamado “db.js”
 Y poner la cadena de conexión:
- import { Sequelize } from "sequelize";
-
- const db = new Sequelize('bienesraices_mvc', 'root', '', {
-     host: 'localhost',
-     port: 3306,
-     dialect: 'mysql',
-     define: {
-         timestamps: true
-     },
-     pool: {  //configura el comportamiento para conexiones nuevas o
existentes, mantener las conexiones que esten vivas
-         max: 5, //maximo de conexiones a mantener
-         min: 0,
-         acquire: 30000, //tiempo de conexion tratando de mantener una
conexion antes de mostrar un error (30000=30 seg.)
-         idle: 10000 //tiempo que debe transcurrir para comenzar una
conexion para liberar estpacio
-     },
-     operatorsAliases: false //sequelize ya no lo utiliza solo evitamos
que lo utilize
- });
-
- export default db;
 lo importamos en nuestro archivo principal “index.js”
- //importamos la conexion a la base de datos
- import db from './config/db.js';
-
- //crear la app
- const app = express();
-
- //conexion a base de datos
- try{
-     await db.authenticate();
-     console.log('Conexion correcta a la base de datos');
- } catch {
-     console.log(error);
- }
 Variables de entorno para seconder nuestros datos de conexión:
- Crear Modelos:
o Creamos una carpeta llamada modelos y dentro los archivos de nuestros modelos
ejemplo:
 models->Usuario.js
 En el cual definimos nuestro modelo
- import {DataTypes} from 'sequelize'
- import db from '../config/db.js'
-
- const Usuario = db.define('usuarios', {
-     nombre: {
-         type: DataTypes.STRING,
-         allowNull: false
-     },
-     email: {
-         type: DataTypes.STRING,
-         allowNull: false
-     },
-     password: {
-         type: DataTypes.STRING,
-         allowNull: false
-     },
-     token: DataTypes.STRING,
-     confirmado: DataTypes.BOOLEAN
- })
-
- export default Usuario
 debemos conectar el routing con UsuarioController:
- import Usuario from "../models/Usuario.js"
 agregar las diferentes funciones por ejemplo:
- import Usuario from "../models/Usuario.js"
-
- const formularioLogin = (req, res) => {
-     res.render('auth/login', {
-         pagina: 'Iniciar sesion'
-
-     })
- }
-
- const formularioRegistro = (req, res) => {
-     res.render('auth/registro', {
-         pagina: 'Registro'
-     })
- }
-
- const registrar = async (req, res) => {
-     const usuario = await Usuario.create(req.body)
-    
-     res.json(usuario)
- }
-
- const formularioOlvidePassword = (req, res) => {
-     res.render('auth/olvide-password', {
-         pagina: 'Olvide mi password'
-     })
- }
-
- export {
-     formularioLogin,
-     formularioRegistro,
-     registrar,
-     formularioOlvidePassword
- }
 En nuestro formulario debemos especificar la ruta que tomara
- form.space-y-5(method="POST" action="/auth/registro")
 en nuestro archivo principal index.js debemos habilitar la lectura de datos
de formulario asi:
- //Habilitar lectura de datos de formulario
- app.use(express.urlencoded({extended: true}))
 para syncronizar nuestra base de datos y crear la tabla
si no existe debemos poner en index.js:
- try{
-     await db.authenticate();
-     db.sync()
-     console.log('Conexion correcta a la base de datos')
- } catch (error) {
-     console.log(error)
- }

- Validación de datos del formulario:

o En la terminal debemos instalar la dependencia express-validator


 npm i express-validator
o Luego debemos importarlo al controlador
- import {check, validationResult} from 'express-validator'
o y en el controlador en la función que estemos usando creamos las validaciones
- const registrar = async (req, res) => {
-     //validacion
-     await check('nombre').notEmpty().withMessage('El campo nombre debe
tener un valor.').run(req)
-     await check('email').isEmail().withMessage('Eso no parece un
email.').run(req)
-     await check('password').isLength({ min: 6 }).withMessage('El
password debe ser de al menos 6 caracteres').run(req)
-     await
check('repetir_password').equals('password').withMessage('Los
passwords no son iguales').run(req)
-
-     let resultado = validationResult(req)
-
-     //return res.json(resultado.array())
-     //verificar que el resultado este vacio
-     if(!resultado.isEmpty()) {
-         //errores
-         return res.render('auth/registro', {
-             pagina: 'Crear Cuenta',
-             errores: resultado.array(),
-             usuario: {
-                 nombre: req.body.nombre,
-                 email: req.body.email
-             }
-         })
-     }
-
-     const usuario = await Usuario.create(req.body)
-    
-     res.json(usuario)
- }
o Para mostrar los errores en el formulario en nuestra vista
- if errores
-             div(class="max-w-md mx-auto my-10")
-                 each error in errores
-                     p.bg-red-600.text-black.uppercase.text-xs.text-
center.p-2.mb-1.font-bold= error.msg
o Para que los datos no se borren del formulario debemos crear una variable que
lleve esos datos en nuestra funcion
- usuario: {
-                 nombre: req.body.nombre,
-                 email: req.body.email
-             }
o Y para mostrar los datos anteriores si existen debemos agregarle al input:
- value= usuario ? usuario.nombre : '')

- Para validar los datos de nuestro formulario:

//validacion
    await check('nombre').notEmpty().withMessage('El campo nombre debe tener
un valor.').run(req)
    await check('email').isEmail().withMessage('Eso no parece un
email.').run(req)
    await check('password').isLength({ min: 6 }).withMessage('El password
debe ser de al menos 6 caracteres.').run(req)
    await
check("repetir_password").equals(req.body.password).withMessage("El password
debe ser igual al anterior").run(req);

    let resultado = validationResult(req)

    //return res.json(resultado.array())
    //verificar que el resultado este vacio
    if(!resultado.isEmpty()) {
        //errores
        return res.render('auth/registro', {
            pagina: 'Crear Cuenta',
            errores: resultado.array(),
            usuario: {
                nombre: req.body.nombre,
                email: req.body.email
            }
        })
    }
o Para verificar si existe un usuario con el mismo email:
- //extraer los datos
-     const { nombre, email, password } = req.body
-
-     //verificar que el usuario no este duplicado
-     const existeUsuario = await Usuario.findOne( { where : {
email } })
-
-     if(existeUsuario) {
-         return res.render('auth/registro', {
-             pagina: 'Crear Cuenta',
-             errores: [{msg: 'El usuario ya existe'}],
-             usuario: {
-                 nombre: req.body.nombre,
-                 email: req.body.email
-             }
-         })
-     }
-
-     console.log(existeUsuario)
o Hash de la Password en la base de datos
 Debemos instalar bcrypt
 npm i bcrypt
 Y luego importarlo al modelo en uso en este caso Usuarios
- import bcrypt from 'bcrypt'
 Ahora desde el modelo Ejemplo Usuario debemos hashear el Password en
este caso lo hace antes de guardar en la base de datos:
- password: {
-         type: DataTypes.STRING,
-         allowNull: false
-     },
-     token: DataTypes.STRING,
-     confirmado: DataTypes.BOOLEAN
- },{
-     hooks: {
-         beforeCreate: async function(usuario) {
-             const salt = await bcrypt.genSalt(10)
-             usuario.password = await bcrypt.hash(usuario.password,
salt);
-         }
-     }
- })
o Almacenar datos a la base de datos:
- //almacenar un usuario
-     await Usuario.create({
-         nombre,
-         email,
-         password,
-         token: 123
-     })
o Generar token único
 Creamos una carpeta “helpers” son funciones que podemos utilizar en
varios lugares.
 Creamos dentro un archivo llamado “tokens.js”
 Dentro del archivo creamos una función que será igual a la forma en que
vamos a crear el id
 Y luego la exportamos:
-
- const generarId = () =>  Math.random().toString(32).substring(2) +
Date.now().toString(32);
-
- export {
-     generarId
- }
o Mostrar mensaje de confirmación al crear cuenta:
 Creamos una carpeta en “views” llamada “templates”
 Y dentro creamos un archivo llamado “mensaje.pug”
 En el mensaje ponemos nuestro template con un parrfo para mostrar el
mensaje:
- extends ../layout/index
- block  contenido
-     div.py-10
-         h1.text-4xl.my-10.font-extrabold.text-center Bienes
-             span.font-normal Raices
-         h2.text-center.text-2xl.font-extrabold= pagina
-        
-
-         p.text-xl.font-bold.text-center.my-10= mensaje
 Y en usuarioController agregamos esto al finalizar la creación del usuario:
- //Mostrar mensaje de confirmacion
-     res.render('templates/mensaje', {
-         pagina: 'Cuenta Creada Correctamente',
-         mensaje: 'Hemos enviado un email de confirmación a tu correo,
presiona en el enlace'
-     })

- Envio de correo de confirmacion:

o Debemos instalar la dependencia Nodemailer


 Npm i nodemailer
o Para probar los correos podemos utilizar mailtrap
 Creamos una cuenta
 Creamos un nuevo inbox
 Buscamos el código para Node.js
var transport = nodemailer.createTransport({
host: "smtp.mailtrap.io",
port: 2525,
auth: {
user: "fe5cd8577744dc",
pass: "e5815909c8ae65"
}
 });
 Y estas credenciales devemos ponerlas en nuestro archivo “.env”
- BD_NOMBRE=bienesraices_mvc
- BD_USER=root
- BD_PASS=
- BD_HOST=localhost
-
- EMAIL_HOST=smtp.mailtrap.io
- EMAIL_PORT=2525
- EMAIL_USER=fe5cd8577744dc
- EMAIL_PASS=e5815909c8ae65
 Luego creamos un archivo dentro de “helpers” llamada “emails.js”
 Dentro de el creamos lo siguiente:
 Debemos tener a mano el código de mailtrap:
- import nodemailer from 'nodemailer'
-
- const emailRegistro = async (datos) => {
-     const transport = nodemailer.createTransport({
-         host: process.env.EMAIL_HOST,
-         port: process.env.EMAIL_PORT,
-         auth: {
-           user: process.env.EMAIL_USER,
-           pass: process.env.EMAIL_PASS
-         }
-     });
-
-     const { email, nombre, token } = datos
-
-     //enviar email
-     await transport.sendMail({
-         from: '[email protected]',
-         to: email,
-         subject: 'Confirma tu Cuenta en BienesRaices',
-         text: 'Confirma tu cuenta en BienesRaices',
-         html: `
-             <p>Hola ${nombre}, comprueba tu cuenta en bienesraices.com
-
-             <p>Tu cuenta ya esta lista, solo debes confirmarla en el
siguiente enclace:
-             <a href=""> Confirmar Cuenta</a> </p>
-
-             <p>Si tu no creaste esta cuenta, puedes ignorar el
mensaje</p>
-         `
-     })
- }
-
- export {
-     emailRegistro
- }
 Debemos importarlo al controlador “usuarioController”
- import { emailRegistro } from '../helpers/emails.js'
 en la function donde se enviara el mensaje:
- //envia email de confirmacion
-     emailRegistro({
-         nombre: usuario.nombre,
-         email: usuario.email,
-         token: usuario.token
-     })
-
-     //Mostrar mensaje de confirmacion
-     res.render('templates/mensaje', {
-         pagina: 'Cuenta Creada Correctamente',
-         mensaje: 'Hemos enviado un email de confirmación a tu correo,
donde debes confirmar tu cuenta.'
-     })

o Agregar un token:
 Agregamos una ruta en “routesusuarioRoutes.js” para cuando el
usuario confirme su cuenta nos redirija a una página de confirmación:
- router.get('/confirmar/:token', confirmar)
 lo agregamos en la importacion
- //importamos formularioLogin
- import { formularioLogin, formularioRegistro, registrar, confirmar,
formularioOlvidePassword} from "../controllers/usuarioController.js";
 en “.env” agregamos “BAKCEND_URL” donde se almacenara la url
- BACKEND_URL=http://localhost
 En la función que enviara el correo desde “emails.js” debemos agregar la
ruta del link
- <a href="${process.env.BACKEND_URL}:${process.env.PORT ??
3000}/auth/confirmar/${token}"> Confirmar Cuenta</a>
 Y en el controlador agregamos la funcion que confirmara el correo
- //funcion que comprueba una cuenta
- const confirmar = (req,res) => {
-     const { token } = req.params;
-     console.log(token)
- }

- Confirmar cuenta con token:


//funcion que comprueba una cuenta
const confirmar = async (req,res) => {
    const { token } = req.params;

    //verificar si el token es valido \


    const usuario = await Usuario.findOne({where:{token}})

    if(!usuario) {
        return res.render('auth/confirmar-cuenta', {
            pagina: 'Error al confirmar tu cuenta',
            mensaje: 'Hubo un error al confirmar tu cuenta, intenta de
nuevo',
            error: true
        })
    }

    //confirmar la cuenta
    usuario.token = null;
    usuario.confirmado = true;
    await usuario.save();

    res.render('auth/confirmar-cuenta', {
        pagina: 'Cuenta confirmada',
        mensaje: 'La cuenta se confirmó correctamente'
    })

   
}
- Habilitando Proteccion CSRF y cookie-parser:
o Sirve para verificar que los formularios si vienende de la aplicacion
o Intalar csurf: npm i csurf cookie-parser
o Debemos importarlo a nuestro archive principal
- import csrf from 'csurf'
- import cookieParser from 'cookie-parser';
 y luego en el mismo archivo principar los debemos habilitar
- // habilitar cookie-parser
- app.use(cookieParser())
-
- //habilitar csrf
- app.use( csrf({cookie: true}))
o luego en nuestra vista en el formulario luego de form debemos colocar el input
que llevara el valor de csrfToken
- input(type="hidden" name="_csrf" value=csrfToken)
o luego en nuestro controlador debemos poner la variable de csrfToken para llevarla
a la vista y al formulario en todas las funciones que requieran de ese formulario:
- const formularioRegistro = (req, res) => {
-
-     res.render('auth/registro', {
-         pagina: 'Registro',
-         csrfToken: req.csrfToken()
-     })
- }
-
- const registrar = async (req, res) => {
-     //validacion
-     await check('nombre').notEmpty().withMessage('El campo nombre debe
tener un valor.').run(req)
-     await check('email').isEmail().withMessage('Eso no parece un
email.').run(req)
-     await check('password').isLength({ min: 6 }).withMessage('El
password debe ser de al menos 6 caracteres.').run(req)
-     await
check("repetir_password").equals(req.body.password).withMessage("El
password debe ser igual al anterior").run(req);
-
-     let resultado = validationResult(req)
-
-     //return res.json(resultado.array())
-     //verificar que el resultado este vacio
-     if(!resultado.isEmpty()) {
-         //errores
-         return res.render('auth/registro', {
-             pagina: 'Crear Cuenta',
-             csrfToken: req.csrfToken(),
-             errores: resultado.array(),
-             usuario: {
-                 nombre: req.body.nombre,
-                 email: req.body.email
-             }
-         })
-     }
-
-     //extraer los datos
-     const { nombre, email, password } = req.body
-
-     //verificar que el usuario no este duplicado
-     const existeUsuario = await Usuario.findOne( { where : { email }
})
-
-     if(existeUsuario) {
-         return res.render('auth/registro', {
-             pagina: 'Crear Cuenta',
-             csrfToken: req.csrfToken(),
-             errores: [{msg: 'El usuario ya existe'}],
-             usuario: {
-                 nombre: req.body.nombre,
-                 email: req.body.email
-             }
-         })
-     }

- Reestablecer contraseña

o
En el controlador debemos
 Importar bcrypt
- import bcrypt from 'bcrypt'
 agregar el nuevo archivo de correo desde helpers “emailOlvidePassword”
- import { emailRegistro, emailOlvidePassword } from
'../helpers/emails.js'
 luego creamos nuestras funciones de olvidar Password y también la de
reestablecer contraseña y las exportamos
- const formularioOlvidePassword = (req, res) => {
-     res.render('auth/olvide-password', {
-         pagina: 'Olvide mi password',
-         csrfToken: req.csrfToken(),
-     })
- }
-
- const resetPassword = async (req, res) => {
-     //validacion
-     await check('email').isEmail().withMessage('Eso no parece un
email.').run(req)
-
-     let resultado = validationResult(req)
-     //verificar que el resultado este vacio
-     if(!resultado.isEmpty()) {
-         //errores
-         return res.render('auth/olvide-password', {
-             pagina: 'Recupera tu acceso a Bienes Raices',
-             csrfToken: req.csrfToken(),
-             errores: resultado.array()
-         })
-     }
-     //buscar usuario
-     const {email} = req.body
-     const usuario = await Usuario.findOne({where:{email}})
-     //si no existe usuario
-     if(!usuario) {
-         return res.render('auth/olvide-password', {
-             pagina: 'Recupera tu acceso a Bienes Raices',
-             csrfToken: req.csrfToken(),
-             errores: [{msg: 'El Email no pertenece a ningún usuario'}]
-         })
-     }
-     //Generar un token y enviar el email\
-     usuario.token = generarId();
-     await usuario.save();
-     //enviar un email
-     emailOlvidePassword({
-         email,
-         nombre: usuario.nombre,
-         token: usuario.token
-     })
-     //renderizar un mensaje
-     //Mostrar mensaje de confirmacion
-     res.render('templates/mensaje', {
-         pagina: 'restablece tu Password',
-         mensaje: 'Hemos enviado un email con las instrucciones.'
-     })
- }
-
- const comprobarToken = async (req,res) => {
-     //recibimos el
-     const {token} = req.params;
-     // buscamos el usuario por el token
-     const usuario = await Usuario.findOne({where:{token}})
-     // verificar si existe usuario
-     // si no existe
-     if(!usuario) {
-         return res.render('auth/confirmar-cuenta', {
-             pagina: 'Restablece tu Password',
-             mensaje: 'Hubo un error al validar tu informacion, intenta
de nuevo',
-             error: true
-         })
-     }
-     //si existe mostramos formulario de validacion
-     res.render('auth/reset-password', {
-         pagina: 'Reestablece tu Password',
-         csrfToken: req.csrfToken(),
-     })
- }
-
- const nuevoPassword = async (req,res) => {
-     // validar el password
-     await check('password').isLength({ min: 6 }).withMessage('El
password debe ser de al menos 6 caracteres.').run(req)
-     let resultado = validationResult(req)
-     //verificar que el resultado este vacio
-     if(!resultado.isEmpty()) {
-         //errores
-         return res.render('auth/reset-password', {
-             pagina: 'Reestablece tu Password',
-             csrfToken: req.csrfToken(),
-             errores: resultado.array()
-         })
-     }
-     const {token} = req.params
-     const {password} = req.body;
-     //Identificar quien hace el cambio
-     const usuario = await Usuario.findOne({where: {token}})
-     //Hashear el nuevo password
-     const salt = await bcrypt.genSalt(10)
-     usuario.password = await bcrypt.hash(password, salt);
-     usuario.token = null;
-
-     await usuario.save();
-    
-     res.render('auth/confirmar-cuenta', {
-         pagina: 'Password Reestablecido',
-         mensaje: 'El Password se guardo correctamente'
-     })
- }
-
- export {
-     formularioLogin,
-     formularioRegistro,
-     registrar,
-     confirmar,
-     formularioOlvidePassword,
-     resetPassword,
-     comprobarToken,
-     nuevoPassword
- }
En la carpeta helpers debemos agregar la función “emailOlvidePassword”
y exportarla para importarla en el controlador para enviar el correo al
usuario para que cambie su Password
- const emailOlvidePassword = async (datos) => {
-     const transport = nodemailer.createTransport({
-         host: process.env.EMAIL_HOST,
-         port: process.env.EMAIL_PORT,
-         auth: {
-           user: process.env.EMAIL_USER,
-           pass: process.env.EMAIL_PASS
-         }
-     });
-
-     const { email, nombre, token } = datos
-
-     //enviar email
-     await transport.sendMail({
-         from: '[email protected]',
-         to: email,
-         subject: 'Restablece tu password en BienesRaices',
-         text: 'Restablece tu password en BienesRaices',
-         html: `
-             <p>Hola ${nombre}, has solicitado reestablecer tu password
en bienesraices.com</p>
-
-             <p>Sigue el siguiente enlace para generar un password
nuevo:
-             <a href="${process.env.BACKEND_URL}:${process.env.PORT ??
3000}/auth/olvide-password/${token}"> Restablecer Password</a> </p>
-
-             <p>Si tu no solicitaste el cambio de password, puedes
ignorar el mensaje.</p>
-         `
-     })
- }
-
- export {
-     emailRegistro,
-     emailOlvidePassword
- }
 En usuarioRoutes debemos agregar las rutas “olvide-password”
- router.post('/olvide-password', resetPassword)
-
- //Almacena el nuevo password
- router.get('/olvide-password/:token', comprobarToken);
- router.post('/olvide-password/:token', nuevoPassword);
 luego debemos crear la vista en la carpeta outh “olvide-password”
- extends ../layout/index
- block  contenido
-     div.py-10
-         h1.text-4xl.my-10.font-extrabold.text-center Bienes
-             span.font-normal Raices
-         h2.text-center.text-2xl.font-extrabold= pagina
-         br
-         p.text-center Escribe tu correo para recuperar acceso a tu
cuenta:
-
-         if errores
-             div(class="max-w-md mx-auto my-10")
-                 each error in errores
-                     p.bg-red-600.text-white.uppercase.text-xs.text-
center.p-2.mb-1.font-bold= error.msg
-
-         div.mt-8.mx-auto.max-w-md
-             div.bg-white.py-8.px-4.shadow
-                 form.space-y-5(method="POST" action="/auth/olvide-
password" noValidate)
-                     input(type="hidden" name="_csrf" value=csrfToken)
-                     div
-                         label.block.text-sm.uppercase.text-gray-
500.mb-3.font-bold(for="email") Tu Email
-                         input#email.w-full.px-3.py-4.border.border-
gray-300.rounded-md.placeholder-gray-400(placeholder="Tu Email"
type="email" name="email")
-
-                     div.flex.items-center.justify-between
-                         a.text-gray-500.text-xs(href="/auth/registro")
No tienes cuenta? Registrarte
-                         a.text-gray-500.text-xs(href="/auth/login") Ya
tienes cuenta? Inicia Sesion
-                    
-                     input(class="w-full bg-indigo-600 hover:bg-indigo-
700 text-white text-center font-bold py-3 font-bold cursor-pointer"
type="submit" value="Enviar correo" )
 Y la vista de “reset-password”
- extends ../layout/index
- block  contenido
-     div.py-10
-         h1.text-4xl.my-10.font-extrabold.text-center Bienes
-             span.font-normal Raices
-         h2.text-center.text-2xl.font-extrabold= pagina
-         br
-         p.text-center Escribe tu correo para recuperar acceso a tu
cuenta:
-
-         if errores
-             div(class="max-w-md mx-auto my-10")
-                 each error in errores
-                     p.bg-red-600.text-white.uppercase.text-xs.text-
center.p-2.mb-1.font-bold= error.msg
-
-         div.mt-8.mx-auto.max-w-md
-             div.bg-white.py-8.px-4.shadow
-                 form.space-y-5(method="POST" noValidate)
-                     input(type="hidden" name="_csrf" value=csrfToken)
-                     div
-                         label.block.text-sm.uppercase.text-gray-
500.mb-3.font-bold(for="password") Coloca tu nuevo Password
-                         input#password.w-full.px-3.py-4.border.border-
gray-300.rounded-md.placeholder-gray-400(placeholder="Tu Nuevo
Password" type="password" name="password")
-                    
-                     input(class="w-full bg-indigo-600 hover:bg-indigo-
700 text-white text-center font-bold py-3 font-bold cursor-pointer"
type="submit" value="Cambiar Password" )

También podría gustarte