다음은 하나의 쿼리 요청을 보내 응답을 받아오는 코드이다. 지금까지 한번에 하나의 요청만을 보내는 방식을 사용했다.
//posts 테이블과 users 테이블을 inner join 시켜서 user와 post 테이블의 정보들을 가져오는 쿼리문
module.exports = async(req,res)=>{
try{
const {postId} = req.body;
const sql = "SELECT users.nickname, posts.content, posts.created_at, posts.generationSelected from posts INNER JOIN users ON posts.writerId = users.id WHERE posts.id = ?";
const params = [postId];
db.query(sql, params, (err,result)=>{
if(err) throw err;
else{
return res.status(200).json({data: result, message:"성공적으로 게시물 정보를 가져왔습니다"});
}
});
}catch(err){
return res.status(404).json({data: null, message:"서버 에러"});
}
}
그런데, 게시물에 관련된 정보 뿐만 아니라 해당 게시물에 달린 댓글 정보들까지 가져와야해서 한번에 두 개의 요청문을 보내고 하나의 응답에 두개의 결과를 보내려고 한다.
mysql 공식문서에 따르면, 다중 선언은 보안 문제로 disalbed 되어있으므로, (SQL injection 공격이 발생할수도 있다) 사용하려면 다음과 같이 수정이 필용하다.
var connection = mysql.createConnection({multipleStatemens:true});
그런데, 나는 config 객체에 선언이 되어 있어서 config/config.js
파일을 다음과 같이 수정해주었다.
const config = {
development: {
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
multipleStatements: true /*다중 쿼리 요청을 가능하게 하기 위해 필요한 속성*/,
},
test: {
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
multipleStatements: true,
},
};
module.exports = async (req, res) => {
try {
const { postId } = req.body;
const sql1 =
"SELECT users.nickname, posts.content, posts.created_at, posts.generationSelected from posts INNER JOIN users ON posts.writerId = users.id WHERE posts.id = ?; ";
const sql1s = mysql.format(sql1, postId);
const sql2 =
"SELECT users.nickname, comments.contents, comments.isSelected, comments.created_at, comments.likes from comments INNER JOIN users ON comments.postId = users.id AND comments.writerId = users.id WHERE comments.postId = ?; ";
const sql2s = mysql.format(sql2, postId);
db.query(sql1s + sql2s, (err, results) => {
if (err) console.log(err);
else {
const postInfo = results[0];
const commentsInfo = results[1];
return res.status(200).send({
data: { postInfo, commentsInfo },
message: "게시물과 해당 댓글 정보가 전달되었습니다",
});
}
});
} catch (err) {
return res.status(404).json({ data: null, message: "서버 에러" });
}
};
그 결과, 다음과 같이 데이터를 잘 보내주고 있음을 확인했다.
처음에는 var connection = mysql.createConnection({multipleStatemens:true});
이 부분을 지나쳐서 한참동안 헤맸는데, 저 속성을 넣어주니 바로 해결되었다. 그런데, 막상 해결되고 나니, SQL injection 공격
이 발생할 수도 있다는 점이 마음에 걸렸다. 다음 포스팅에서는 이 공격에 대해서 다뤄보도록 하겠다.
reference