mysql(6) 다중쿼리 요청하기

Creating the dots·2021년 10월 8일
0

project-1-dagachi

목록 보기
6/11

다음은 하나의 쿼리 요청을 보내 응답을 받아오는 코드이다. 지금까지 한번에 하나의 요청만을 보내는 방식을 사용했다.

//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

profile
어제보다 나은 오늘을 만드는 중

0개의 댓글