- Node.js_#2_Database 연동 (MySQL 기준)2025년 01월 21일
- Hoony Teddy
- 작성자
- 2025.01.21.:56
1. mysql2 설치
mysql2 : Node.js를 위한 MySQL 클라이언트 라이브러리로, 콜백/프로미스/async&awayt 패턴을 지원한다.
npm install mysql2
2. DB와 Node.js를 연결할 db.js 작성
//db.jsconst mysql = require("mysql2/promise");
// createPool을 통해 커넥션 (Pool) 생성// 여러 요청이 동시에 들어와도 안정적으로 DB에 접근할 수 있음const pool = mysql.createPool({host: "localhost", // MySQL 서버 주소 (로컬호스트로 예시)user: ~아이디~, // MySQL 사용자password: ~비밀번호~, // MySQL 비밀번호database: "ted_test_db", // 연결할 DB 이름waitForConnections: true, // pool이 가득차서 사용 가능한 커넥션이 없을 때, 새 쿼리 요청을 대기시키기 : trueconnectionLimit: 10, //최대 커넥션 수queueLimit: 0, // waitForConnections가 true일 때, 얼마나 많은 쿼리 요청을 대기시킬 것인가 (0: 무한)});
// 앞서 작성한 pool 객체를 모듈로 내보내기module.exports = pool;3. Database 생성
Mysql에서
- Connection Name : ted_test_db
- HostName : localhost
- Port : 3306 <- MySQL 기본 포트
- UserName : ~아이디~
- PassWord : ~비밀번호~
4. 환경변수 (.env) 사용하기
민감한 정보는 .env파일에 저장하고, process.env.~를 사용하여 .env파일에서 불러오기
4-1. .env에서 불러오는 데에 사용되는 dotenv 패키지 설치
npm install dotenv
4-2. .env파일 생성
// .env DB_ID=HoonsID DB_PW=HoonsPW
4-3 민감 정보 치환
// db.js require("dotenv").config(); const pool = mysql.createPool({ ... user: process.env.DB_ID, // MySQL 사용자 password: process.env.DB_PW, // MySQL 비밀번호 ...
4-4. .gitignore에 .env 추가
.env파일은 git에 올리면 안 되므로, .gitignore에 추가하는 것이 일반적이다.
my-project/ ├── .gitignore ├── package.json ├── node_modules/ └── index.js
# node_modules 폴더 무시 node_modules/ # 환경 변수 설정 파일 무시 (.env) .env # 빌드 산출물(예: dist/, build/) 무시 dist/ build/ # 로그 파일 *.log # 다른 OS별 불필요한 파일 .DS_Store Thumbs.db
5. DB 활용 엔드포인트 구현
5-1. 기본 GET 라우팅
app.get("/db/selectAll", async (req, res) => { try { // pool.query() <- 첫번쨰 요소[rows]가 실제 쿼리 결과 const [rows] = await pool.query("SELECT * FROM users"); res.json(rows); } catch (e) { console.error(e); res.status(500).send("DB Error"); } });
5-2. URL 파라미터 사용
app.get("/db/selectName/:name", async (req, res) => { try { // URL 파라미터에서 name값 가져오기 const selName = req.params.name; //SQL 인젝션을 방지하기 위한 파라미터 바인딩 사용 const data = await pool.query("SELECT * FROM users WHERE name = ? LIMIT 1", [selName]); res.json(data[0]); } catch (e) { console.error(e); res.status(500).send("DB Error"); } });
**이때, 파라미터 바인딩을 사용하지 않고, 직접 문자열 삽입을 할 경우,const [rows] = await.pool.query(`SELECT * FROM users WHERE name = ${selName}`);
selName에 Alice' OR '1' = '1과 같은 악의적인 문자열이 들어온다면양 끝에 "를 씌워 대입하게 되므로
아래와 같이 SQL Injection에 노출될 수가 있다.SELECT * FROM users WHERE name = 'Alice' OR '1'='1'
따라서, 파라미터 바인딩을 이용해 "이 값은 쿼리 로직이 아니라 단순 데이터임"을 명시해주어야 한다.// (안전) Prepared statement + 파라미터 바인딩 const [rows] = await pool.query('SELECT * FROM users WHERE name = ?', [selName]);
이렇게 하면 Alice' OR '1' = 1' 등이 들어와도, 해당 값을 단순 문자열로만 인식하므로, 따옴표가 깨지지 않고 의도치 않은 SQL 구문으로 해석되지 않으므로 Injection을 방어할 수 있다.
5-3. POST 라우팅
app.post("/db/createUser", async (req, res) => { try { // client가 보낸 사용자 데이터를 req.body에서 꺼냄 // app.use(express.json()) 미들웨어가 있어서 JSON 형식을 자동으로 파싱해줌 const { name, email } = req.body; const [rows] = await pool.query("INSERT INTO users(name, email) VALUES(?,?)", [name, email]); res.status(201).json({ message: "New User Created!", insertId: rows.insertId, name: name, email: email, }); } catch (e) { console.error(e); res.status(500).send("DB Error"); } });
http://localhost:3000/db/createUser의 POSTMAN 결과 'Node.js' 카테고리의 다른 글
Node.js_#1_프로젝트 초기 설정 (0) 2025.01.21 다음글이전글이전 글이 없습니다.댓글
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)