Tengo problemas al hacer algunas cosas complejas dentro del middleware. Sé que debería hacer esto en una ruta o en alguna función pequeña, pero no tuve otra opción.
Este es todo el middleware:
app.use(async function addReqUser(req,res,next) { if (req.cookies) { let token = req.cookies['session-token']; let user = {}; async function verify() { //google auth function const ticket = await client.verifyIdToken({ idToken: token, audience: CLIENT_ID, }); const payload = ticket.getPayload(); user.name = payload.name; user.email = payload.email; user.picture = payload.picture; } verify() .then(async ()=>{ req.user = user; const user = await User.find({ email: req.user.email }).select("_id").exec(); req.user.id = user[0]._id res.locals.user = req.user //populate the user with an id next(); }) .catch(err=>{ console.log(err) return res.redirect('/') }) } next() }) The error just says [ERR HTTP_HEADERS_SENT] Cannot set headers after they are sent back to the client
Ayúdame con esto.
Su rápida respuesta es apreciada.
Si se establece req.cookies y la llamada de verify() es exitosa, next() se ejecutará dos veces : una vez después de la invocación asíncrona de verify() y una vez más al final de la función .then .
Por otro lado, si verify() falla, la llamada res.redirect en la función .catch establece un encabezado después de la primera ejecución de next() .
Ambos pueden conducir al error observado. Un middleware debería
next() (¡una vez!) ores.send ), pero no llame a next() .No ha usado async y espera la función de verificación, puede modificar su app.use al siguiente código
app.use(async function addReqUser(req, res, next) { if (req.cookies) { let token = req.cookies['session-token']; let user; async function verify() { //google auth function return client.verifyIdToken({ idToken: token, audience: CLIENT_ID, }); } const response = await verify() const payload = response.getPayload() if (payload.email) { user.name = payload.name; user.email = payload.email; user.picture = payload.picture; const userDoc = await User.find({ email: req.user.email }).select("_id").exec(); req.user = userDoc; req.user.id = userDoc[0]._id; res.locals.user = req.user //populate the user with an id return next() } else { return res.redirect('/') } } next() })Al usar .then en verificar, el código no está esperando verificar () Promesa de completar y siguiente () después de que el bloque si se ejecuta primero
Se estaba llamando a req.cookies y next() se estaba ejecutando dos veces. Después de algunas sugerencias y codificación aquí está la solución:
app.use(function addReqUser(req, res, next) { if (Object.hasOwnProperty.bind(req.cookies)('session-token')) { //has a session-token let user = {}; async function verify() { let token = req.cookies['session-token']; //google auth function const ticket = await client.verifyIdToken({ idToken: token, audience: CLIENT_ID, }); const payload = ticket.getPayload() if (payload) { user.name = payload.name; user.email = payload.email; user.picture = payload.picture; req.user = user; const userDoc = await User.find({ email: req.user.email }).select("_id").exec(); req.user.id = userDoc[0]._id; res.locals.user = req.user //populate the user with an id } } verify() .then(()=>{ next(); }) .catch(err=>{ console.log(err) res.redirect('/') }) } else { next(); } })