Cannot set headers after they are sent to the client - Express JS - javascript

I am pretty much new to node / express and following a youtube tutorial to build a MERN Stack app. But my node server is giving this error
I tried restarting server many times it happening again and again. I got the idea it happens when we send two responses for one request but I don't think its the case here.
Btw here is the route it is pointing to in the error (in the try catch error response line)
// GET RANDOM
router.get("/random", verify, async (req, res) => {
const type = req.query.type;
let movie;
try {
if (type === "series") {
movie = await Movie.aggregate([
{ $match: { isSeries: true } },
{ $sample: { size: 1 } },
]);
} else {
movie = await Movie.aggregate([
{ $match: { isSeries: false } },
{ $sample: { size: 1 } },
]);
}
res.status(200).json(movie); //checked here by console logging it comes here only once
} catch (err) {
res.status(500).json(err); //the error pointing to this line
}
});
Just in case, here is the verify function code:
function verify(req,res,next) {
const authHeader = req.headers.token;
if(authHeader){
const token = authHeader.split(' ')[1];
jwt.verify(token,process.env.SECRET_KEY,(err,user) => {
if(err) res.status(403).json("Token is not valid");
req.user = user;
next();
})
} else{
return res.status(401).json("Unauthorized");
}
}

Related

My Login System in Node.js is not working

I'm using Node.js and MySQL for a login system. My problem is, login system is not working when I use async-await and promises. It's not giving errors but page keeps reloading and user cannot enter the system. What can the problem be? Is there a problem in my await declarations. I'm kind of new at fullstack programming. Thanks for your help.
At the top of the login controller, there is a async arrow function and below its code block, there are multiple awaits which are defined for some database calls and bcrypting password.
Should I return the database connection as .promise()
or not a promise? Sometimes code is working and user can enter, but sometimes cannot.
This Code Block For User Login
exports.login = async (req, res) => {
try {
const { email, password } = req.body;
// if (!email || !password) {
// return res.status(400).render("giriş_yap", {
// msg: "Lütfen e-mail veya şifrenizi giriniz",
// msg_type: "error",
// });
// }
const allDB = await login_db.query(`select * from users where email='${email}'`);
const user = allDB[0] ;
//console.log(user[0]) ;
if (user.length <= 0) {
return res.status(401).render("giriş_yap", {
msg: "Sistemde kaydınız bulunamadı",
msg_type: "error",
});
} else {
const passwordMatch = (await bcrypt.compare(password, user[0].PASS))
if (!passwordMatch) {
return res.status(401).render("giriş_yap", {
msg: "Emailiniz veya Şifreniz hatalı",
msg_type: "error",
});
} else {
const id = user[0].ID;
const token =jwt.sign({ id: id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRES_IN,
});
//console.log("The Token is " + token);
const cookieOptions = {
expires: new Date(
Date.now() +
process.env.JWT_COOKIE_EXPIRES * 24 * 60 * 60 * 1000
),
httpOnly: true,
};
res.cookie("joes", token, cookieOptions);
res.status(200).redirect("/anasayfa");
}
}
} catch (error) {
console.log(error);
}
};
This Code Block for mysql database connection
const mySql = require("mysql2");
const config = require("../config_db");
const login_db = mySql.createConnection(config.db_login);
login_db.connect(function (err) {
if (err) {
console.log(err);
}
console.log("Kullanici bilgileri veritabanina başariyla baglandiniz.");
});
module.exports = login_db.promise();
Are you sure you didn't forget in your front-end this code ?
e.preventDefault()
If not, please share the front-end code also.
Also in your code, be careful with your console.log in the catch block on your login function. It can throw to infinite api call.

error sending header, express comparison code

I wondered. And in general, I need help.
app.get('/admin', async (req,res) => {
let tq = await User.findOne({ where: { link: req.params.userId } })
// if (tq.status === req.originalUrl.split('/')[1])
//myname(req, res)
return res.render('/admin')
// } else {
// res.end('w')
// }
}
if I do this, then I will not get mistakes. (spoiler: cors on)
async function myname(req, res) {
let tq = await User.findOne({ where: { link: req.params.userId } })
if (tq.status === req.originalUrl.split('/')[1]) {
next()
} else {
res.end('w')
}
}
//and I will connect it to the code above (imagine that there are no crutches, a regular render of the page
then we get an error of something type: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
what's my problem? Do I have to use conditional operators everywhere?...

Opening Web Socket connection from app.get (Express)

I am running the Bitfinex Websocket connection from node.js server using express.
I have an API endpoint so that I ask for the specific book from the link (e.g http://localhost:4000/BTC-USD/buy/100)
The problem is that when I try to make the connection from the app.get the websocket doesn't respond
It only responds from outside. The problem is that, that way I cant pass the parameter so I can establish the proper connection. The code I can't perform
app.get("/:pair/:type/:amount", async (req,res) => {
let { pair, type, amount } = req.params;
try {
wsConnection(pair);
wsMessageHandler()
const result = await simulateEffectivePrice({ pair, type, amount })
res.send({ "effectivePrice" : result })
} catch (error) {
res.send({"error" : error.message})
}
})
The code that works:
wsConnection();
wsMessageHandler()
app.get("/:pair/:type/:amount", async (req,res) => {
let { pair, type, amount } = req.params
try {
// if (type !== "buy" || type !== "sell") throw new Error ("wrong type input")
const result = await simulateEffectivePrice({pair,type,amount})
res.send({ "effectivePrice" : result })
} catch (error) {
res.send({"error" : error.message})
}
})
The wsConnection functions is this, (it requires the book you want to receive information from)
const wsConnection = async () => {
let msg = JSON.stringify({
event: 'subscribe',
channel: 'book',
symbol: 'tBTCUSD',
// len: "25"
})
try {
w.on('open', () => {
w.send(JSON.stringify({ event: 'conf', flags: 65536 + 131072 }))
w.send(msg)
})
} catch (error) {
throw new Error("BUILD CUSTOM ERROR")
}
}
"symbol" would need to be the parameter specified on the endpoint by the user
Thank you very much

How to handle 401 error status code error in Node.js/Express?

I am working on login functionality in my project, now, flow looks like this (from front-end to back-end):
async login() {
await login({
password: this.userPassword,
login: this.userLogin,
twoFactor: this.twoFactor
}).then((res) => {
if (res.error) {
//
} else {
console.log(res)
}
})
}
And here is starts problems, as you can see if something goes wrong, I return status code 401 and some error message. When I login with correct data, there is no problem with getting token, but when I provide wrong data I have external pending login endpoint in development tools in browser and then, after some time, Error: Request failed with status code 401 in front end terminal. Without this status(401) with just JSON it works fine, but when I try to add 401 code, application crashes.
const userService = require('./../services/userService')
const crypto = require('./../services/cryptoService')
const jwt = require('./../services/jwtService')
const twoFactorService = require('node-2fa')
module.exports = {
login: async (req, res) => {
let { login, password, twoFactor } = req.body
password = crypto.encrypt(password, process.env.APP_KEY)
const result = await userService.getUserToLogin(login, password)
if (!result) {
res.status(401).json({
error: 'Unauthorized'
})
} else {
const faCode = result.twofatoken
const result2F = twoFactorService.verifyToken(faCode, twoFactor);
if ( !result2F || result2F.delta !== 0 ) {
res.status(401).json({
error: 'Unauthorized'
})
} else {
const userId = crypto.encrypt(result.id, process.env.CRYPTO_KEY)
const token = await jwt.sign({
uxd: userId,
});
res.json(token);
}
}
}
}
Actually, I have no idea on what to do with that and how to handle this error.
Ok, here is the answer. Actually, you just need to handle this error in your router:
router.post('/login', async (req, res) => {
try {
const data = await api.post('/login', req.body)
res.json(data.data)
} catch (e) {
// Probably you have here just console.log(e), but this way, you can handle it
res.status(e.response.status).json(e.response.data)
}
})

User authorization using custom middleware in loopback

I have made VerifyUserAccess middleware in loopback as below:
module.exports = function(options) {
return function storeCurrentUser(req, res, next) {
if (!req.accessToken) {
return next();
}
app.models.UserModel.findById(req.accessToken.userId, function(err, user) {
if (err) {
return next(err);
}
if (!user) {
return next(new Error('No user with this access token was found.'));
}
const LoopBackContext = require('loopback-context');
const loopbackContext = LoopBackContext.getCurrentContext();
if (loopbackContext) {
loopbackContext.set('currentUser', user);
}
next();
});
};
};
And Also I added it in middleware.json as below:
...
"initial": {
"./middleware/verify_user_access": {},
...
}
...
But problem is that always loopbackContext I got null.
And the second question is that how to access currentUser result in API. I have done below:
Gameversionandtype.GetGameversionandtypeByGameTypeID = (ctx, callback) =>
{
const LoopBackContext = require('loopback-context');
const context = LoopBackContext.getCurrentContext();
const currentUserResult = context && context.get('currentUserResult');
console.log('currentUser.username: ', currentUserResult.id);
...
...
}
And Please let me know that how to set currentUser result and how to get it in API. I have referred documentation as well loopback-context npm module but I can not find any solutions. Thanking you in advance.

Categories

Resources