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

Configuración Node.js y Express MVC

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)
116 vistas29 páginas

Configuración Node.js y Express MVC

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

Proyecto Bienes y Raices

- Instalar [Link] descargándolo desde la página web


- Iniciar proyecto desde Visual Studio Code dentro de la carpeta del proyecto
- Crear nuestro archivo [Link] 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": "[Link]",
-   "scripts": {
-     "test": "echo \"Error: no test specified\" && exit 1"
-   },
-   "keywords": [
-     "MVC",
-     "Pug",
-     "Tailwind",
-     "MySQL",
-     "Sequelize"
-   ],
-   "author": "ozarata@[Link]",
-   "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 [Link] 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 [Link]
o Crear archivo principal que es el que debes correr, ejemplo: [Link], [Link],
[Link], [Link] etc…(incluso puede ser el nombre del proyecto).
o En el archivo [Link] 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 ./[Link]"
-   },
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 ./[Link]

 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 [Link] en el apartado
de scripts:
- "scripts": {
-     "start": "node ./[Link]",
-     "server": "nodemon [Link]"
-   },
 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 [Link]

 [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 [Link]`
 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 [Link]:
 Versión anterior (CommonJS):
- const express = require('express');
-
- //crear la app
- const app = express();
-
- //routing
- [Link]('/', function(req, res) {
-     [Link]('Hola mundo');
- })
-
- //Definir un puerto y arrancar el proyecto
- const port = 3000;
-
- [Link](port, () => {
-     [Link](`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 [Link]
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 [Link]`
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
- [Link]('/', function(req, res) {
-     [Link]('Hola mundo');
- })
 Version Actual (ECMAScript):
 Ya no se usa llamar la librería con “require”
 Ahora debemos habilitar ECMAScript
 Debemos abrir [Link]:
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->[Link]
 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 [Link]
- //importamos express
- import express from "express";
- //definimos router
- const router = [Link]();
-
- //routing
- [Link]('/', function(req, res) {
-     [Link]('Hola mundo');
- });
-
- [Link]('/nosotros', function(req, res) {
-     [Link]('Informacion de nosotros');
- });
-
- //exportamos router
- export default router
 luego podemos importar [Link] a los archivos en que lo
necesitemos
 Ejemplo: [Link]
- //importamos express
- import express from 'express'
- //importamos [Link]
- import usuariosRoutes from './routes/[Link]';
-
- //crear la app
- const app = express();
-
- //routing
- [Link]('/', usuariosRoutes);
- [Link]('/nosotros', usuariosRoutes);
-
- //Definir un puerto y arrancar el proyecto
- const port = 3000;
-
- [Link](port, () => {
-     [Link](`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
- [Link]('/', usuariosRoutes);
 de esta manera llamamos a todas las rutas de [Link]
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: [Link]
 Debemos poner que tipo de petición es.(Get, Post, etc.)
 Podemos usar también route para englobar peticiones con la
misma ruta ejemplo:
- [Link]('/')
-     .get(function(req, res) {
-         [Link]('Hola mundo en express');
-     })
-     .post(function(req, res) {
-         [Link]({msg: 'Respuesta de tipo Post'});
-     })
 En ves de verlas por separado:
- [Link]('/', function(req, res) {
-     [Link]('Hola mundo en express');
- });
-
- [Link]('/', function(req, res) {
-     [Link]({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 [Link] 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
[Link] y habilitamos pug:
- //habilitar Pub
- [Link]('view engine', 'pug');
- [Link]('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->[Link]
 las vistas tienen que tener el tipo de archivo .pug
 debemos de rutear en [Link] nuestros modulos por ejemplo
para [Link] 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
- [Link]('/auth', usuariosRoutes);
 llamar la vista en el modulo:
- [Link]('/login', function(req, res) {
-     [Link]('auth/login');
- });
 [Link] 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:
-    [Link]-center Login
 Pasar información a la vista:
- [Link]('/login', function(req, res) {
-     [Link]('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 [Link]
o Creamos el archivo [Link] dentro de la carpeta
 Controllers->[Link]
o usuarioController: pondremos todas nuestras funciones y las exportamos
o ejemplo:
- const formularioLogin = (req, res) => {
-     [Link]('auth/login', {
-         autenticado: false
-     })
- }
-
- export {
-     formularioLogin
- }
o Luego debemos importarla en [Link] y llamarlas
- //importamos express
- import express from "express";
-
- //importamos formularioLogin
- import { formularioLogin } from "../controllers/[Link]";
-
- //definimos router
- const router = [Link]();
-
- [Link]('/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 [Link] 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 [Link] 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
- [Link]( [Link]('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 [Link]
 En la carpeta css creamos el archivo [Link]
 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
 [Link]
 [Link]
o En archivo [Link] debemos:
 Decirle en que carpeta o archivos esta el archivo
css
 Por defecto lo veremos asi:
- /** @type {import('tailwindcss').Config} */
- [Link] = {
-   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 [Link] debemos agregar un
script:
- "scripts": {
-     "start": "node ./[Link]",
-     "server": "nodemon [Link]",
-     "css": "postcss public/css/[Link] -o public/css/[Link]"
-   },
 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/[Link] 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 [Link] para que se actualice
automáticamente:
- "css": "postcss public/css/[Link] -o public/css/[Link] --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 [Link] 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: [Link]({ nombre: ‘Casa’})
o Algunos ORM:
 Prisma
 Mongoose
 TypeORM
 Sequelize
 [Link]
o Conectando Bases de datos usando SEQUELIZE en [Link]:
 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 “[Link]”
 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 “[Link]”
- //importamos la conexion a la base de datos
- import db from './config/[Link]';
-
- //crear la app
- const app = express();
-
- //conexion a base de datos
- try{
-     await [Link]();
-     [Link]('Conexion correcta a la base de datos');
- } catch {
-     [Link](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->[Link]
 En el cual definimos nuestro modelo
- import {DataTypes} from 'sequelize'
- import db from '../config/[Link]'
-
- const Usuario = [Link]('usuarios', {
-     nombre: {
-         type: [Link],
-         allowNull: false
-     },
-     email: {
-         type: [Link],
-         allowNull: false
-     },
-     password: {
-         type: [Link],
-         allowNull: false
-     },
-     token: [Link],
-     confirmado: [Link]
- })
-
- export default Usuario
 debemos conectar el routing con UsuarioController:
- import Usuario from "../models/[Link]"
 agregar las diferentes funciones por ejemplo:
- import Usuario from "../models/[Link]"
-
- const formularioLogin = (req, res) => {
-     [Link]('auth/login', {
-         pagina: 'Iniciar sesion'
-
-     })
- }
-
- const formularioRegistro = (req, res) => {
-     [Link]('auth/registro', {
-         pagina: 'Registro'
-     })
- }
-
- const registrar = async (req, res) => {
-     const usuario = await [Link]([Link])
-    
-     [Link](usuario)
- }
-
- const formularioOlvidePassword = (req, res) => {
-     [Link]('auth/olvide-password', {
-         pagina: 'Olvide mi password'
-     })
- }
-
- export {
-     formularioLogin,
-     formularioRegistro,
-     registrar,
-     formularioOlvidePassword
- }
 En nuestro formulario debemos especificar la ruta que tomara
- [Link]-y-5(method="POST" action="/auth/registro")
 en nuestro archivo principal [Link] debemos habilitar la lectura de datos
de formulario asi:
- //Habilitar lectura de datos de formulario
- [Link]([Link]({extended: true}))
 para syncronizar nuestra base de datos y crear la tabla
si no existe debemos poner en [Link]:
- try{
-     await [Link]();
-     [Link]()
-     [Link]('Conexion correcta a la base de datos')
- } catch (error) {
-     [Link](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 [Link]([Link]())
-     //verificar que el resultado este vacio
-     if(![Link]()) {
-         //errores
-         return [Link]('auth/registro', {
-             pagina: 'Crear Cuenta',
-             errores: [Link](),
-             usuario: {
-                 nombre: [Link],
-                 email: [Link]
-             }
-         })
-     }
-
-     const usuario = await [Link]([Link])
-    
-     [Link](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
-                     [Link]-
[Link]-bold= [Link]
o Para que los datos no se borren del formulario debemos crear una variable que
lleve esos datos en nuestra funcion
- usuario: {
-                 nombre: [Link],
-                 email: [Link]
-             }
o Y para mostrar los datos anteriores si existen debemos agregarle al input:
- value= usuario ? [Link] : '')

- 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([Link]).withMessage("El password
debe ser igual al anterior").run(req);

    let resultado = validationResult(req)

    //return [Link]([Link]())
    //verificar que el resultado este vacio
    if(![Link]()) {
        //errores
        return [Link]('auth/registro', {
            pagina: 'Crear Cuenta',
            errores: [Link](),
            usuario: {
                nombre: [Link],
                email: [Link]
            }
        })
    }
o Para verificar si existe un usuario con el mismo email:
- //extraer los datos
-     const { nombre, email, password } = [Link]
-
-     //verificar que el usuario no este duplicado
-     const existeUsuario = await [Link]( { where : {
email } })
-
-     if(existeUsuario) {
-         return [Link]('auth/registro', {
-             pagina: 'Crear Cuenta',
-             errores: [{msg: 'El usuario ya existe'}],
-             usuario: {
-                 nombre: [Link],
-                 email: [Link]
-             }
-         })
-     }
-
-     [Link](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: [Link],
-         allowNull: false
-     },
-     token: [Link],
-     confirmado: [Link]
- },{
-     hooks: {
-         beforeCreate: async function(usuario) {
-             const salt = await [Link](10)
-             [Link] = await [Link]([Link],
salt);
-         }
-     }
- })
o Almacenar datos a la base de datos:
- //almacenar un usuario
-     await [Link]({
-         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 “[Link]”
 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 = () =>  [Link]().toString(32).substring(2) +
[Link]().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 “[Link]”
 En el mensaje ponemos nuestro template con un parrfo para mostrar el
mensaje:
- extends ../layout/index
- block  contenido
-     [Link]-10
-         [Link]-center Bienes
-             [Link]-normal Raices
-         [Link]-extrabold= pagina
-        
-
-         [Link]-10= mensaje
 Y en usuarioController agregamos esto al finalizar la creación del usuario:
- //Mostrar mensaje de confirmacion
-     [Link]('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 [Link]
var transport = [Link]({
host: "[Link]",
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=[Link]
- EMAIL_PORT=2525
- EMAIL_USER=fe5cd8577744dc
- EMAIL_PASS=e5815909c8ae65
 Luego creamos un archivo dentro de “helpers” llamada “[Link]”
 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 = [Link]({
-         host: [Link].EMAIL_HOST,
-         port: [Link].EMAIL_PORT,
-         auth: {
-           user: [Link].EMAIL_USER,
-           pass: [Link].EMAIL_PASS
-         }
-     });
-
-     const { email, nombre, token } = datos
-
-     //enviar email
-     await [Link]({
-         from: 'info@[Link]',
-         to: email,
-         subject: 'Confirma tu Cuenta en BienesRaices',
-         text: 'Confirma tu cuenta en BienesRaices',
-         html: `
-             <p>Hola ${nombre}, comprueba tu cuenta en [Link]
-
-             <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/[Link]'
 en la function donde se enviara el mensaje:
- //envia email de confirmacion
-     emailRegistro({
-         nombre: [Link],
-         email: [Link],
-         token: [Link]
-     })
-
-     //Mostrar mensaje de confirmacion
-     [Link]('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[Link]” para cuando el
usuario confirme su cuenta nos redirija a una página de confirmación:
- [Link]('/confirmar/:token', confirmar)
 lo agregamos en la importacion
- //importamos formularioLogin
- import { formularioLogin, formularioRegistro, registrar, confirmar,
formularioOlvidePassword} from "../controllers/[Link]";
 en “.env” agregamos “BAKCEND_URL” donde se almacenara la url
- BACKEND_URL=[Link]
 En la función que enviara el correo desde “[Link]” debemos agregar la
ruta del link
- <a href="${[Link].BACKEND_URL}:${[Link] ??
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 } = [Link];
-     [Link](token)
- }

- Confirmar cuenta con token:


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

    //verificar si el token es valido \


    const usuario = await [Link]({where:{token}})

    if(!usuario) {
        return [Link]('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
    [Link] = null;
    [Link] = true;
    await [Link]();

    [Link]('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
- [Link](cookieParser())
-
- //habilitar csrf
- [Link]( 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) => {
-
-     [Link]('auth/registro', {
-         pagina: 'Registro',
-         csrfToken: [Link]()
-     })
- }
-
- 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([Link]).withMessage("El
password debe ser igual al anterior").run(req);
-
-     let resultado = validationResult(req)
-
-     //return [Link]([Link]())
-     //verificar que el resultado este vacio
-     if(![Link]()) {
-         //errores
-         return [Link]('auth/registro', {
-             pagina: 'Crear Cuenta',
-             csrfToken: [Link](),
-             errores: [Link](),
-             usuario: {
-                 nombre: [Link],
-                 email: [Link]
-             }
-         })
-     }
-
-     //extraer los datos
-     const { nombre, email, password } = [Link]
-
-     //verificar que el usuario no este duplicado
-     const existeUsuario = await [Link]( { where : { email }
})
-
-     if(existeUsuario) {
-         return [Link]('auth/registro', {
-             pagina: 'Crear Cuenta',
-             csrfToken: [Link](),
-             errores: [{msg: 'El usuario ya existe'}],
-             usuario: {
-                 nombre: [Link],
-                 email: [Link]
-             }
-         })
-     }

- 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/[Link]'
 luego creamos nuestras funciones de olvidar Password y también la de
reestablecer contraseña y las exportamos
- const formularioOlvidePassword = (req, res) => {
-     [Link]('auth/olvide-password', {
-         pagina: 'Olvide mi password',
-         csrfToken: [Link](),
-     })
- }
-
- 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(![Link]()) {
-         //errores
-         return [Link]('auth/olvide-password', {
-             pagina: 'Recupera tu acceso a Bienes Raices',
-             csrfToken: [Link](),
-             errores: [Link]()
-         })
-     }
-     //buscar usuario
-     const {email} = [Link]
-     const usuario = await [Link]({where:{email}})
-     //si no existe usuario
-     if(!usuario) {
-         return [Link]('auth/olvide-password', {
-             pagina: 'Recupera tu acceso a Bienes Raices',
-             csrfToken: [Link](),
-             errores: [{msg: 'El Email no pertenece a ningún usuario'}]
-         })
-     }
-     //Generar un token y enviar el email\
-     [Link] = generarId();
-     await [Link]();
-     //enviar un email
-     emailOlvidePassword({
-         email,
-         nombre: [Link],
-         token: [Link]
-     })
-     //renderizar un mensaje
-     //Mostrar mensaje de confirmacion
-     [Link]('templates/mensaje', {
-         pagina: 'restablece tu Password',
-         mensaje: 'Hemos enviado un email con las instrucciones.'
-     })
- }
-
- const comprobarToken = async (req,res) => {
-     //recibimos el
-     const {token} = [Link];
-     // buscamos el usuario por el token
-     const usuario = await [Link]({where:{token}})
-     // verificar si existe usuario
-     // si no existe
-     if(!usuario) {
-         return [Link]('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
-     [Link]('auth/reset-password', {
-         pagina: 'Reestablece tu Password',
-         csrfToken: [Link](),
-     })
- }
-
- 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(![Link]()) {
-         //errores
-         return [Link]('auth/reset-password', {
-             pagina: 'Reestablece tu Password',
-             csrfToken: [Link](),
-             errores: [Link]()
-         })
-     }
-     const {token} = [Link]
-     const {password} = [Link];
-     //Identificar quien hace el cambio
-     const usuario = await [Link]({where: {token}})
-     //Hashear el nuevo password
-     const salt = await [Link](10)
-     [Link] = await [Link](password, salt);
-     [Link] = null;
-
-     await [Link]();
-    
-     [Link]('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 = [Link]({
-         host: [Link].EMAIL_HOST,
-         port: [Link].EMAIL_PORT,
-         auth: {
-           user: [Link].EMAIL_USER,
-           pass: [Link].EMAIL_PASS
-         }
-     });
-
-     const { email, nombre, token } = datos
-
-     //enviar email
-     await [Link]({
-         from: 'info@[Link]',
-         to: email,
-         subject: 'Restablece tu password en BienesRaices',
-         text: 'Restablece tu password en BienesRaices',
-         html: `
-             <p>Hola ${nombre}, has solicitado reestablecer tu password
en [Link]</p>
-
-             <p>Sigue el siguiente enlace para generar un password
nuevo:
-             <a href="${[Link].BACKEND_URL}:${[Link] ??
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”
- [Link]('/olvide-password', resetPassword)
-
- //Almacena el nuevo password
- [Link]('/olvide-password/:token', comprobarToken);
- [Link]('/olvide-password/:token', nuevoPassword);
 luego debemos crear la vista en la carpeta outh “olvide-password”
- extends ../layout/index
- block  contenido
-     [Link]-10
-         [Link]-center Bienes
-             [Link]-normal Raices
-         [Link]-extrabold= pagina
-         br
-         [Link]-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
-                     [Link]-
[Link]-bold= [Link]
-
-         [Link]-w-md
-             [Link]
-                 [Link]-y-5(method="POST" action="/auth/olvide-
password" noValidate)
-                     input(type="hidden" name="_csrf" value=csrfToken)
-                     div
-                         [Link]-gray-
[Link]-bold(for="email") Tu Email
-                         input#[Link]-
[Link]-gray-400(placeholder="Tu Email"
type="email" name="email")
-
-                     [Link]-between
-                         [Link]-xs(href="/auth/registro")
No tienes cuenta? Registrarte
-                         [Link]-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
-     [Link]-10
-         [Link]-center Bienes
-             [Link]-normal Raices
-         [Link]-extrabold= pagina
-         br
-         [Link]-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
-                     [Link]-
[Link]-bold= [Link]
-
-         [Link]-w-md
-             [Link]
-                 [Link]-y-5(method="POST" noValidate)
-                     input(type="hidden" name="_csrf" value=csrfToken)
-                     div
-                         [Link]-gray-
[Link]-bold(for="password") Coloca tu nuevo Password
-                         input#[Link]-
[Link]-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