이전에 작성한 .query()관련 글을 보고 오는 걸 추천합니다. [링크]
그런데 where의 조건이 동적으로 들어온다면 ?
Group by의 조건이 동적으로 들어온다면 ?
그래서 필요한 2가지 정도의 방식이 있습니다.
conn.query(
SELECT * FROM users WHERE email = '${email}'
function (err, results) {
if (results.length) {
res.status(200).json(results);
} else {
res.status(404).json({ error: "존재하지 않는 id입니다." });
}
}
);
위 코드는 SQL 쿼리를 작성할 때 문자열 보간법(템플릿 리터럴)을 사용하여 email 값을 직접 SQL 쿼리에 삽입합니다.
이 방식은 보안에 취약할 수 있습니다.
만약 email 변수에 악의적인 SQL 코드가 포함되어 있다면, SQL 인젝션 공격에 노출될 수 있습니다
예시:
const email = "test@example.com'; DROP TABLE users; --";
이 경우, 쿼리는 다음과 같이 변형되어 실행될 수 있습니다:
SELECT * FROM users WHERE email = 'test@example.com'; DROP TABLE users; --';
이렇게 되면 DROP TABLE users;가 실행되어 데이터베이스의 테이블이 삭제될 수 있습니다.
conn.query
SELECT * FROM users WHERE email = ?,
email,
function (err, results) {
if (results.length) {
res.status(200).json(results);
} else {
res.status(404).json({ error: "존재하지 않는 id입니다." });
}
}
);
이 코드는 파라미터 바인딩 방식으로 SQL 쿼리를 작성합니다.
?는 SQL 쿼리 내에서 placeholder 역할을 하며, 실제 값은 email 변수로 바인딩됩니다
이렇게 하면 SQL 인젝션 공격을 방지할 수 있습니다.
SQL 인젝션 공격자는 ?에 악의적인 SQL 코드를 삽입할 수 없으며, 파라미터는 안전하게 처리됩니다.
// 회원 가입 (INSERT INTO)
router.post("/join", (req, res) => {
if (req.body == {}) {
res.status(400).json({ error: "userId, password, name은 필수입니다." });
} else {
const { email, name, password, contact } = req.body;
conn.query(
`INSERT INTO users (email, name, password, contact) VALUES (?,?,?,?)`,
// 배열([])을 사용해서 차례로 입력 할 수 있게 해줍니다.
[email, name, password, contact],
function (err, result) {
res.status(201).json({ message: `${name}님 환영합니다.` });
}
);
}
});
중간에 보면 [email, name, password, contact] 처럼 배열을 사용해서 (?,?,?,?) 구문 순서대로 데이터를 입력해 줄 수 있습니다.