실습 - MySQL release의 실습

YoonSuk Choi·2024년 12월 11일

6주차_MVC 실습

목록 보기
2/4

6주차_MySQL_release 실습

MVC와 MySQL의 연결 내용

  • MVC(Model-View-Controller) 패턴을 기반으로 Express.js와 MySQL을 연결하여 회원가입, 로그인, 프로필 수정 및 삭제 기능 구현

실습 결과

  1. 회원가입

    • 유효한 ID, 비밀번호, 이름 입력 시 데이터베이스에 성공적으로 저장되고, JSON 응답을 통해 성공 여부 반환.
    • 이미 존재하는 ID로 가입을 시도하면 실패 응답 처리.
  2. 로그인

    • 유효한 자격증명(ID 및 비밀번호)으로 로그인하면 사용자 정보를 반환하며, 프로필 페이지로 리디렉션.
    • 잘못된 자격증명으로 로그인 시도 시 실패 응답 처리.
  3. 회원정보 수정 및 탈퇴

    • 이름 및 비밀번호 수정 시 데이터베이스에 반영되며, 수정 성공 여부 반환.
    • 탈퇴 시 해당 사용자가 데이터베이스에서 삭제되고, 성공 여부 반환.
  4. 뷰 렌더링 및 페이지 이동

    • 각각의 뷰 파일이 요청에 따라 정상적으로 렌더링되며, 경로에 따른 페이지 이동이 원활히 작동.

폴더 구조와 코드의 역할

MVC_MySQL_release
├── controller/
│   ├── Cuser.js
├── model/
│   ├── User.js
├── node_modules/
│   ├── 다양한 파일
├── routes/
│   ├── user.js
├── views/
│   │   ├── include/
│   │   │   ├── include.ejs
│   ├── 404.ejs
│   ├── index.ejs
│   ├── profile.ejs
│   ├── signin.ejs
│   ├── signup.ejs
├── .gitignore
├── app.js
├── init.sql
├── package-lock.json
└── package.json
  • controller/

    • Cuser.js 주요 기능 : 회원가입 처리, 로그인 처리, 회원 정보 수정, 회원 탈퇴.
  • model/

    • User.js 주요 기능 : 주요 기능: 유저 데이터 삽입, 조회, 수정, 삭제.
  • routes/

    • user.js 주요 기능 : 사용자 관련 요청 경로(/user)를 정의하고 컨트롤러와 연결
    • 주요 라우트 : 회원가입(/signup), 로그인(/signin), 프로필 수정(/profile/edit), 프로필 삭제(/profile/delete).
  • views/

    • index.ejs: 회원가입 및 로그인 페이지로 이동할 수 있는 링크 제공
    • signup.ejs: 회원가입 페이지, 사용자로부터 ID, 비밀번호, 이름을 입력
    • signin.ejs: 로그인 페이지, 사용자로부터 ID와 비밀번호를 입력
    • profile.ejs: 로그인 후 유저 정보를 수정, 탈퇴 페이지
    • 404.ejs: 에러 페이지입니다.

코드별 내용

controller/Cuser.js

const User = require("../model/User");

// 회원가입 처리
exports.signup = (req, res) => {
  const { userid, name, pw } = req.body;
  User.signup({ userid, name, pw }, (result) => {
    if (result) {
      res.status(201).json({ success: true, message: "회원가입 성공" });
    } else {
      res.status(500).json({ success: false, message: "회원가입 실패" });
    }
  });
};

// 로그인 처리
exports.signin = (req, res) => {
  const { userid, pw } = req.body;
  User.signin({ userid, pw }, (user) => {
    if (user) {
      res.status(200).json({ success: true, user });
    } else {
      res.status(401).json({ success: false, message: "로그인 실패" });
    }
  });
};

// 회원정보 수정
exports.editProfile = (req, res) => {
  const { id, name, pw } = req.body;
  User.update({ id, name, pw }, (result) => {
    if (result) {
      res.status(200).json({ success: true, message: "정보 수정 성공" });
    } else {
      res.status(500).json({ success: false, message: "정보 수정 실패" });
    }
  });
};

// 회원탈퇴 처리
exports.deleteProfile = (req, res) => {
  const { id } = req.body;
  User.delete(id, (result) => {
    if (result) {
      res.status(200).json({ success: true, message: "회원 탈퇴 성공" });
    } else {
      res.status(500).json({ success: false, message: "회원 탈퇴 실패" });
    }
  });
};

model/User.js

const mysql = require("mysql2");

const connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "3144",
database: "sesac",
});

connection.connect();

// 회원가입
exports.signup = (data, callback) => {
const query = "INSERT INTO user (userid, name, pw) VALUES (?, ?, ?)";
connection.query(query, [data.userid, data.name, data.pw], (err, result) => {
  if (err) {
    console.error(err);
    return callback(false);
  }
  callback(true);
});
};

// 로그인
exports.signin = (data, callback) => {
const query = "SELECT * FROM user WHERE userid = ? AND pw = ?";
connection.query(query, [data.userid, data.pw], (err, results) => {
  if (err) {
    console.error(err);
    return callback(null);
  }
  callback(results[0]);
});
};

// 회원정보 수정
exports.update = (data, callback) => {
const query = "UPDATE user SET name = ?, pw = ? WHERE id = ?";
connection.query(query, [data.name, data.pw, data.id], (err, result) => {
  if (err) {
    console.error(err);
    return callback(false);
  }
  callback(true);
});
};

// 회원탈퇴
exports.delete = (id, callback) => {
const query = "DELETE FROM user WHERE id = ?";
connection.query(query, [id], (err, result) => {
  if (err) {
    console.error(err);
    return callback(false);
  }
  callback(true);
});
};

routes/user.js

const express = require("express");
const router = express.Router();
const Cuser = require("../controller/Cuser");

// 회원가입 페이지 렌더링 (GET /signup)
router.get("/signup", (req, res) => {
  res.render("signup", { title: "회원가입" });
});

// 회원가입 처리 (POST /signup)
router.post("/signup", Cuser.signup);

// 로그인 페이지 렌더링 (GET /signin)
router.get("/signin", (req, res) => {
  res.render("signin", { title: "로그인" });
});

// 로그인 처리 (POST /signin)
router.post("/signin", Cuser.signin);

// 회원정보 수정 (POST /profile/edit)
router.post("/profile/edit", Cuser.editProfile);

// 회원탈퇴 처리 (DELETE /profile/delete)
router.delete("/profile/delete", Cuser.deleteProfile);

module.exports = router;

뷰 파일 (views/)

404.ejs

<!DOCTYPE html>
<html lang="ko">
  <%- include('include/include', { title: '404 Error' })%>
  <body>
    <h1>🚨404 Error</h1>
    <p>죄송합니다. 해당 URL은 접근할 수 없는 주소입니다.</p>
    <!-- TODO: href 속성값 설정하기 -->
    <a href="/">HOME</a>
  </body>
</html>

index.ejs

<!DOCTYPE html>
<html lang="ko">
  <%- include('include/include', { title: '실습 | 회원가입/로그인 구현' })%>
  <body>
    <h1>실습. 회원가입과 로그인 DB 연동</h1>
    <!-- TODO: href 속성값 설정하기 -->
    <a href="/user/signup">회원가입</a>
    <a href="/user/signin">로그인</a>
  </body>
</html>

profile.ejs

<!DOCTYPE html>
<html lang="ko">
  <%- include('include/include', { title: '회원 정보' })%>
  <body>
    <h1>회원 정보</h1>
    <!-- TODO: href 속성값 설정하기 -->
    <a href="#">HOME</a>
    <p>ID 수정 불가능, Password, Name 수정 가능</p>

    <!-- TODO: 각 input의 value 값을 로그인 한 사람의 정보로 채우기 -->
    <form name="form_profile">
      <label for="userid">ID</label>
      <input type="hidden" id="id" value="" />
      <!-- readonly: userid는 수정 불가능 (조건임) -->
      <input
        id="userid"
        type="text"
        name="userid"
        value="<%= user.userid %>"
        readonly
      />
      <label for="password">Password</label>
      <input
        id="password"
        type="password"
        name="pw"
        value="<%= user.pw %>"
        required
      />
      <label for="name">Name</label>
      <input
        id="name"
        type="text"
        name="name"
        value="<%= user.name %>"
        required
      />
      <button type="button" onclick="profileEdit();">Edit</button>
      <button type="button" onclick="profileDelete();">Delete</button>
    </form>

    <script>
      // TODO: [Login] 버튼 클릭시 서버에 회원 정보 수정 요청하기
      // POST /user/profile/edit
      function profileEdit() {}

      // TODO: [Login] 버튼 클릭시 서버에 회원 정보 삭제 요청하기
      // POST /user/profile/delete
      function profileDelete() {}
    </script>
  </body>
</html>

signin.ejs

<!DOCTYPE html>
<html lang="ko">
  <%- include('include/include', { title: '로그인' })%>
  <body>
    <h1>로그인</h1>
    <script>
      function login() {
        const data = {
          userid: document.getElementById("userid").value,
          pw: document.getElementById("password").value,
        };

        axios.post("/user/signin", data).then((response) => {
          if (response.data.success) {
            // 로그인 성공 시 사용자 정보를 form에 삽입 후 제출
            document.forms["form_info"].userid.value =
              response.data.user.userid;
            document.forms["form_info"].submit();
          } else {
            // 로그인 실패 시 알림 및 입력값 초기화
            alert("로그인 실패");
            document.forms["form_login"].reset();
          }
        });
      }
    </script>

    <form name="form_info" action="/user/profile" method="POST">
      <input type="hidden" name="userid" />
    </form>

    <form name="form_login">
      <label for="userid">ID</label>
      <input id="userid" type="text" name="userid" required /><br />
      <label for="password">Password</label>
      <input id="password" type="password" name="pw" required /><br />
      <button type="button" onclick="login();">Login</button>
    </form>

    <!-- 회원가입 페이지로 이동 -->
    <a href="/user/signup">Register</a>
  </body>
</html>

signup.ejs

<!DOCTYPE html>
<html lang="ko">
  <%- include('include/include', { title: '회원가입' })%>
  <body>
    <h1>회원가입</h1>
    <script>
      function register() {
        const data = {
          userid: document.getElementById("userid").value,
          pw: document.getElementById("password").value,
          name: document.getElementById("nickname").value,
        };

        axios.post("/user/signup", data).then((response) => {
          if (response.data.success) {
            // 회원가입 성공 시 로그인 페이지로 이동
            alert("회원가입 성공");
            document.location.href = "/user/signin";
          } else {
            // 회원가입 실패 시 알림 표시
            alert("회원가입 실패");
          }
        });
      }
    </script>

    <form name="form_register">
      <label for="userid">ID</label>
      <input id="userid" type="text" name="userid" required /><br />
      <label for="password">Password</label>
      <input id="password" type="password" name="pw" required /><br />
      <label for="nickname">Name</label>
      <input id="nickname" type="text" name="name" required /><br />
      <button type="button" onclick="register();">Register</button>
    </form>

    <!-- 로그인 페이지로 이동 -->
    <a href="/user/signin">Login</a>
  </body>
</html>

app.js

const express = require("express");
const app = express();
const PORT = 8000;

// 라우터 파일 불러오기
const userRouter = require("./routes/user");

// EJS 설정
app.set("view engine", "ejs");
app.set("views", "./views");

// 정적 파일 경로 설정
app.use("/static", express.static(__dirname + "/static"));

// body-parser 기능 (JSON 데이터 및 URL-encoded 데이터 파싱)
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

// 기본 경로 처리
app.get("/", (req, res) => {
  res.redirect("/user/signin");
});

// 라우팅 설정
app.use("/user", userRouter);

// 404 에러 처리
app.use((req, res) => {
  res.status(404).render("404", { title: "404 Error" });
});

// 서버 실행
app.listen(PORT, () => {
  console.log(`http://localhost:${PORT}`);
});


profile
Name : 최윤석(YoonSuk Choi)

0개의 댓글