</link>
Descargue el archivo template_navbar. Fuente: Tutorial Republic - Snippets
Instale los módulos mysql2, express-generator, express-cli, sequelize, sequelize-cli y sequelize-auto de manera global.
npm i -g mysql2 express-generator express-cli sequelize sequelize-cli sequelize-auto
Compruebe el funcionamiento de los comandos, con:
express --help
sequelize-cli --help
sequelize-auto --help
NOTA: En caso de no obtener una respuesta de los comandos, consulte la sección de errores No se reconoce como comando.
Desde la línea de comandos, inicie el servidor:
npm run autostart
Cree el archivo ‘security/views/partials/navbar.ejs’. Copie todo el contenido de navbar.html dentro de ‘security/views/partials/navbar.ejs’.
Edite la vista
‘security/views/crud.ejs’, con:
...
<div class="container-xl">
<!-- 1. Navbar -->
<%- include('partials/navbar.ejs') %>
<div class="table-responsive">
...
</div>
</div>
...
Compruebe la salida de la URL http://localhost:3000/users
(STOP 1) Versiona local y remotamente el repositorio security.
Desde la línea de comandos, acceda a la interfaz de NodeJS, con:
node
Genere y copie la secuencia de caracteres aleatorios, con:
> require('crypto').randomBytes(16).toString('base64');
> .exit
En la raíz del proyecto, cree el archivo ‘.env’. Agregue la variable SALT y asigne la secuencia de caracteres aleatorios.
SALT='...8uUYwT...'
Edite el servidor
‘app.js’, con:
/* 1. Carga de variables de entorno */
require('dotenv').config()
var createError = require('http-errors');
var express = require('express');
...
Edite el enrutador ‘security/routes/users.js’, con:
var express = require('express');
var router = express.Router();
/* 1. Importe el módulo crypto */
let crypto = require('crypto');
...
/* GET users listing. */
router.get( ... );
/* POST user. */
/* 2. Cree el callback asíncrono que responda al método POST */
router.post('/', async (req, res) => {
/* 3. Desestructure los elementos en el cuerpo del requerimiento */
let { name, password, idrole } = req.body;
try {
/* 4. Utilice la variable SALT para encriptar la variable password. */
let salt = process.env.SALT
let hash = crypto.createHmac('sha512', salt).update(password).digest("base64");
let passwordHash = salt + "$" + hash
/* 5. Guarde el registro mediante el método create */
let user = await models.users.create({ name: name, password: passwordHash })
/* 6. Redireccione a la ruta con la vista principal '/users' */
res.redirect('/users')
} catch (error) {
res.status(400).send(error)
}
})
module.exports = router;
Edite la vista ‘security/views/crud.ejs’.
...
<!-- Edit Modal HTML -->
<div id="addEmployeeModal" class="modal fade">
...
<form method="post" action="/users">
...
...
Acceda a URL http://localhost:3000/users, acceda al botón Add User y complete el formulario para crear un nuevo usuario con los siguientes datos:
Name: admin
Password: admin
(STOP 2) Versiona local y remotamente el repositorio security.
En grupos de tres (3) personas:
Completen las siguientes tareas. Pueden utilizar la documentación oficial o los servicios de un LLM.
Edite el enrutador ‘security/routes/users.js’, con:
...
router.get('/', async function(req, res, next) {
/* 3. Uso del método findAll */
...
let rolesCollection = /* Recupere de todos los registros mediante la instancia Roles. */
/* 4. Paso de parámetros a la vista */
res.render('crud', { ... rolesArray: /* Colección de roles */ });
});
module.exports = router;
...
...
/* 1. Instanciación del modelo */
const sequelize = require('../models/index.js').sequelize;
var initModels = require("../models/init-models");
var models = initModels( sequelize );
/* GET users listing. */
/* 2. Convierta el callback en asíncrono */
router.get('/', async function(req, res, next) {
/* 3. Uso del método findAll */
let usersCollection = await models.users.findAll({ })
let rolesCollection = await models.roles.findAll({ })
/* 4. Paso de parámetros a la vista */
res.render('crud', { title: 'CRUD of users', usersArray: usersCollection, rolesArray: rolesCollection });
});
Edite la vista ‘security/views/crud.ejs’, con:
...
<!-- 6. Arreglo de roles -->
<select name="idrole" class="form-control">
<option value="null" selected disabled
class="form-control">Select an item</option>
</select>
<!-- 6. Arreglo de roles -->
<select name="idrole" class="form-control">
<option value="null" selected disabled
class="form-control">Select an
item</option>
<% rolesArray.forEach( role => { %>
<option
value="<%=role.idrole%>"
class="form-control"><%=role.name%></option>
<% }) %>
</select>
Acceda a URL http://localhost:3000/users, acceda al botón Add User y verifique que se muestren los roles.
(STOP 3) Versiona local y remotamente el repositorio security.
Completen las siguientes tareas. Pueden utilizar la documentación oficial o los servicios de un LLM.
Edite el enrutador ‘security/routes/users.js’, con:
...
/* POST user. */
router.post('/', async (req, res) => {
...
try {
...
let user = ...
/* 5.1. Utilice el model.user_roles para crear la relación ( user.iduser , idrole) */
/* 6. Redireccione a la ruta con la vista principal '/users' */
...
} catch (error) {
res.status(400).send(error)
}
})
module.exports = router;
...
/* POST user. */
router.post('/', async (req, res) => {
...
try {
...
let user = ...
/* 5.1. Utilice el model.user_roles para crear la relación ( user.iduser , idrole) */
await models.users_roles.create({ users_iduser: user.iduser, roles_idrole: idrole })
/* 6. Redireccione a la ruta con la vista principal '/users' */
...
} catch (error) {
res.status(400).send(error)
}
})
module.exports = router;
Acceda a URL http://localhost:3000/users, acceda al botón Add User y complete el formulario para crear un nuevo usuario con los siguientes datos:
Name: user
Password: user
Role: user
(STOP 4) Versiona local y remotamente el repositorio security.
Completen las siguientes tareas. Pueden utilizar la documentación oficial o los servicios de un LLM.
Edite el enrutador ‘security/routes/users.js’, con:
Incluya todos los modelos asociados con el modelo users y sus asociaciones anidadas (recursivamente). Revise Including everything
Agregue la clave raw para que la respuesta solo contenga datos (raw: true) y la clave nest para habilitar el acceso anidado (nest: true). Revise Raw Queries
...
router.get('/', async function(req, res, next) {
/* 3. Uso del método findAll */
let usersCollection = await models.users.findAll({
/* 3.1. Including everything */
/* 3.2. Raw Queries */
})
...
res.render( ... );
});
module.exports = router;
...
...
router.get('/', async function(req, res, next) {
/* 3. Uso del método findAll */
let usersCollection = await models.users.findAll({
/* 3.1. Including everything */
include: { all: true, nested: true },
/* 3.2. Raw Queries */
raw: true,
nest: true,
})
...
res.render( ... );
});
module.exports = router;
Edite la vista ‘security/views/crud.ejs’, con:
...
<td>
<!--
Dato relacionado
users->users_roles->roles.name
-->
</td>
...
...
<td>
<!--
Dato relacionado
users->users_roles->roles.name
-->
<%= user.users_roles.roles_idrole_role.name %>
</td>
Compruebe la salida de la URL http://localhost:3000/users
(STOP 5) Versiona local y remotamente el repositorio security.
Como almacenar passwords en una BD para que estos no estén expuestos en el caso de un acceso a esta base:
— Fernando Romo (@El_Pop) August 18, 2022
el truco es reconstruir el password a partir de su hash y el salt previamente generado y almacenado. pic.twitter.com/sdESoBZOeg
Sequelize, ORM, archivos estáticos, vista, enrutador, modelo, renderización, encriptación, SALT