app.post("/login", async (req, res) => {
// Destructure Req Body
const { email, password } = req.body;
// Validate Body
if (!email || !password) {
res.status(400).json({ success: false, message: "PARAMS_MISSING" });
}
// Build the SQL query
const query = `SELECT * FROM user WHERE email = "${email}"`;
// Get the user from DB
const user = await db(query);
// Check if password is valid
const isPasswordValid = decryptPassword(user.hash_password, password);
// Return if password is not valid
if (!isPasswordValid) {
res.status(401).json({ success: false, message: "INAVLID_PASSWORD" });
}
// Generate Token
const token = generateToken({ id: user.id, email: user.email });
// Save Cookie
res.cookie("token", token, { maxAge: 900000, httpOnly: true });
res.end();
// Return
res.json({ success: true, message: "USER_AUTHENTICATED" });
});
UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
I m getting this error again and again. I'm facing this weird issue in NodeJS when using it with Passport.js, Express. Basically, I keep getting the error saying "Cannot set headers after they are sent to the client", even though I'm not sending more than one header.
This error means the 'res' object respond twice. E.g: in your '// Validate body
' if the password or email are missing your http connection respond 'res.status().json()
.'(note that is closing the http connection), but as you didn't stop the execution of the code, it carries on then it may respond a second time in the // Return if password is not valid
which create the err as the header can not be set twice and the connection is already close.
Than more here you error is Unhandled, as an Async function reject, the error must be handle, wrapping the code in a try{} catch(e){} will fix it.
So that should fix your issues
app.post("/login", async (req, res) => {
try{
// Destructure Req Body
const { email, password } = req.body;
// Validate Body
if (!email || !password) {
res.status(400).json({ success: false, message: "PARAMS_MISSING" });
return // stop execution of the function
}
// Build the SQL query
const query = `SELECT * FROM user WHERE email = "${email}"`;
// Get the user from DB
const user = await db(query);
// Check if password is valid
const isPasswordValid = decryptPassword(user.hash_password, password);
// Return if password is not valid
if (!isPasswordValid) {
res.status(401).json({ success: false, message: "INAVLID_PASSWORD" });
return // stop exec of the function
}
// Generate Token
const token = generateToken({ id: user.id, email: user.email });
// Save Cookie
res.cookie("token", token, { maxAge: 900000, httpOnly: true });
res.end();
// Return
res.json({ success: true, message: "USER_AUTHENTICATED" });
} catch(err) {
console.error(err) // code to handle the err
}
});
But still, a problem remain as at the end of your script, you have a res.end()(which terminate the connection) and right after a res.json() which will fail as the connection has been close the line before (than more the statusCode is missing)