I am having issues while doing some complex stuff inside middleware. I know i should be getting this done in a route or some small function but I had no choice.
This is the entire 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()
})
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
The error just says [ERR HTTP_HEADERS_SENT] Cannot set headers after they are sent back to the client
Help me with this.
Your fast response in appreciated.
CodePudding user response:
If req.cookies
is set and the verify()
call is successful, next()
will be executed twice: once after the asynchronous invocation of verify()
and once more at the end of the .then
function.
On the other hand, if verify()
fails, the res.redirect
call in the .catch
function sets a header after the first execution of next()
.
Both can lead to the observed error. A middleware should either
- optionally set headers and then call
next()
(once!) or - optionally set headers and then send a response (e.g., via
res.send
), but not callnext()
.
CodePudding user response:
You have not used async and await for verify function, you can modify you app.use to the following code
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()
})
While using the .then on verify, the code is not waiting for verify() Promise to complete & next() after the if block is executed first