• 티스토리 홈
  • 프로필사진
    Hoony Teddy
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
Hoony Teddy
  • 프로필사진
    Hoony Teddy
    • 분류 전체보기 (19)
      • JAVA (7)
      • HTML (7)
      • Node.js (2)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • 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.js
        const 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이 가득차서 사용 가능한 커넥션이 없을 때, 새 쿼리 요청을 대기시키기 : true
          connectionLimit: 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일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바