Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

174
Visualizações
ExpressJS Middleware: el orden de ejecución de Promises no es correcto

Quiero crear un Express Middleware para realizar una verificación básica si el par de usuario/contraseña en el encabezado de autorización existe en un archivo JSON (propósito educativo). Lo agregué en una aplicación de conversión de unidades muy simple.

El problema es que recibo un 403 en lugar del recurso cuando el nombre de usuario y la contraseña son correctos.

Descubrí que cuando realizo una solicitud, Promise.then en el middleware se ejecuta antes de que se cumpla Promise en mi función findUserByCredentials. Vea una ilustración del problema en el tercer fragmento de código a continuación.

índice.js

 const express = require('express') const app = express() const port = process.env.PORT || 3000 const findUserByCredentials = require("./lib/find-user"); app.use(function (req, res, next) { if (req.headers) { let header = req.headers.authorization || ''; let [type, payload] = header.split(' '); if (type === 'Basic') { let credentials = Buffer.from(payload, 'base64').toString('ascii'); let [username, password] = credentials.split(':'); findUserByCredentials({username, password}).then(() => { console.log("next") next(); }).catch(() => { console.log("403") res.sendStatus(403); }); } } else { next(); } }); app.get('/inchtocm', (req, res) => { const cm = parseFloat(req.query.inches) * 2.54; res.send({"unit": "cm", "value": cm}); }); app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) }) module.exports = app;

./lib/buscar-usuario.js

 const bcrypt = require('bcrypt'); const jsonfile = require('../users.json'); let findUserByCredentials = () => (object) => { const username = object.username; const password = object.password; return new Promise((resolve, reject) => { jsonfile.forEach(user => { if (user.username === username) { bcrypt.compare(password, user.password).then((buffer) => { if (buffer) { console.log("resolve") resolve(); } else { console.log("reject") reject(); } }); } }); reject(); }); }; module.exports = findUserByCredentials();

Consola del servidor después de enviar una solicitud

 Example app listening at http://localhost:3000 403 resolve

¿Cómo puedo obligar a Express a esperar a que finalice la primera Promesa antes de realizar la segunda operación?

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Para tener un mejor control sobre el orden de tus promesas y también tener un código menos anidado, debes usar la sintaxis async/await . Puedes leer más sobre esto aquí .

Básicamente, lo que hace es permitirle... bueno, esperar a que finalice una operación asíncrona antes de continuar. Si usa await antes de algo que devuelve una Promise (como su findUserByCredentials ), asignará a la variable con qué resuelve su promesa, por ejemplo:

 const myPromise = () => { return new Promise(resolve => resolve(3)); } const myFunc = async () => { const number = await myPromise(); console.log(number); // Output: 3 }

Yo reformularía su función findUserByCredentials así:

 const bcrypt = require('bcrypt'); const jsonfile = require('../users.json'); const findUserByCredentials = async (object) => { const username = object.username; const password = object.password; // This assumes there's only a single unique user with a specific username const potentialUser = jsonfile.find(user => user.username === username); if (!potentialUser) { throw new Error('wrong credentials') } const passHashCompare = await bcrypt.compare(password, potentialUser.password); if (!passHashCompare) { throw new Error('wrong credentials') } }; module.exports = findUserByCredentials;

De esta manera, está menos anidado, es más legible y funciona en el orden que necesita. Puede ir aún más lejos con este principio y hacer que su middleware (la función que está pasando a app.use ) también sea una async function y use la palabra clave await en lugar de .then() y .catch()

about 4 years ago · Juan Pablo Isaza Relatório

0

Cambiaría el código para usar las últimas características del lenguaje javascript relacionado con el código async/await de esa manera, puede tener un mejor control de su flujo de ejecución.

Voy a modificar su código de la siguiente manera:

En primer lugar para la función findUserByCredentials :

 const bcrypt = require('bcrypt'); const jsonfile = require('../users.json'); const findUserByCredentials = async (object) => { const username = object.username; const password = object.password; const user = jsonfile.find(user => user.username == username); if (user) await bcrypt.compareSync(user.password, password); return false; }; module.exports = findUserByCredentials;

En segundo lugar para el index.js

 const express = require('express') const app = express() const port = process.env.PORT || 3000 const findUserByCredentials = require("./lib/find-user"); app.use(async (req, res, next) => { if (req.headers) { let header = req.headers.authorization || ''; let [type, payload] = header.split(' '); if (type === 'Basic') { const credentials = Buffer.from(payload, 'base64').toString('ascii'); const [username, password] = credentials.split(':'); const result = await findUserByCredentials({username, password}) if(result) { return next() } return res.sendStatus(403); } return res.sendStatus(403); } return next(); }); app.get('/inchtocm', (req, res) => { const cm = parseFloat(req.query.inches) * 2.54; res.send({"unit": "cm", "value": cm}); }); app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) }) module.exports = app;

Es muy importante aprender a usar código asíncrono en Nodejs porque es un solo hilo y si no se usa correctamente, puede bloquearlo y el rendimiento de su aplicación no será óptimo, también async/await es azúcar sintáctico de lenguajes javascript que permite Para escribir código asincrónico limpio, intente usar las últimas novedades de la especificación del lenguaje porque están creadas para facilitarnos la vida.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda