Home Server - 04
Post
X

Server - 04

로그인, 회원가입 기능 구현 (Server)


DB 설계

이전에 설계한 member 테이블을 삭제하고 새로 user 테이블을 정의해보겠습니다.

이전 모델링 포스팅


user 테이블 설계

먼저 회원 정보 관련 요구사항을 추가 정리합니다.

  1. 회원 정보는 아이디, 비밀번호, 이름 등의 정보가 유지되어야합니다.

validation 내용 추가 예정

  1. 아이디는 4 ~ 12 글자이어야 하고 영어 대소문자, 숫자로만 구성되어야합니다.

  2. 비밀번호는 4 ~ 12 글자이어야 하고 영어, 숫자, 특수문자(!@#$%^&*)가 하나 이상 포함되어야합니다.


요구사항 1번에서 회원 엔티티의 속성으로 아이디, 비밀번호, 이름를 얻을 수 있습니다.


DB 명명 규칙에 따라 테이블 명세서를 작성합니다.

참고 글 : DB 명명 규칙

user-table-specs


이제 Workbench에 테이블 명세서를 바탕으로 ER 다이어그램을 수정합니다.

참고 글 : 물리적 데이터 모델링


express 서버 API 구현


app.js

app.js파일에 user 라우터를 추가합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import express from "express";
import bodyParser from "body-parser";
import cors from "cors";
import morganMiddleware from "./src/middleware/morgan.js";
import movieRouter from "./src/routes/movie.route.js";
import userRouter from "./src/routes/user.route.js";

const app = express();

...

// router
app.use("/movie", movieRouter);
app.use("/user", userRouter);

...

export default app;

router

routes 폴더에 user.route.js 파일을 생성한 후 express router를 작성합니다.

1
2
3
4
5
6
7
8
9
import express from "express";
import ctrl from "../controllers/user.controller.js";

const router = express.Router();

router.post("/login", ctrl.login); // 유저 로그인
router.post("/register", ctrl.register); // 유저 회원가입

export default router;

controller

controllers 폴더에 user.controller.js 파일을 생성한 후 작성하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import userStorage from "../models/user.model.js";

export default {
  login: async (req, res, next) => {
    let response = {};

    try {
      let { id, password } = req.body;

      const user = await userStorage.getUserInfo(id);

      // 아이디 없음
      if (!user) {
        response = {
          success: false,
          msg: "아이디가 존재하지 않습니다",
        };
      } else {
        if (password === user.password) {
          response = {
            success: true,
            msg: "로그인 성공",
          };
        } else {
          response = {
            success: false,
            msg: "비밀번호가 틀렸습니다",
          };
        }
      }

      res.json(response);
    } catch (err) {
      next(err);
    }
  },

  register: async (req, res, next) => {
    let response = {};

    try {
      let { id, password } = req.body;

      const checked = await userStorage.checkUser(id);

      if (checked) {
        response = { success: false, msg: "이미 존재하는 아이디입니다" };
      } else {
        // DB에 새로운 사용자 등록
        await userStorage.createUser(req.body);

        response = { success: true, msg: "회원가입 완료." };
      }

      res.json(response);
    } catch (err) {
      next(err);
    }
  },
};

model

models 폴더에 user.model.js 파일을 생성한 후 작성해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import conn from "../config/dbPool.js";

class userStorage {
  static async checkUser(id) {
    try {
      await conn.beginTransaction();

      const [rows] = await conn.query(
        "select EXISTS (SELECT id FROM user WHERE id = ?) AS isExist",
        [id]
      );

      await conn.commit();

      return rows[0].isExist;
    } catch (err) {
      await conn.rollback();

      throw err;
    } finally {
      conn.release();
    }
  }

  static async getUserInfo(id) {
    try {
      await conn.beginTransaction();

      const [rows] = await conn.query("SELECT * FROM user WHERE id = ?", [id]);

      await conn.commit();

      return rows[0];
    } catch (err) {
      await conn.rollback();

      throw err;
    } finally {
      conn.release();
    }
  }

  static async createUser(userInfo) {
    try {
      await conn.beginTransaction();

      const [rows] = await conn.query(
        "INSERT INTO user (id, password, name) VALUES (?, ?, ?)",
        [userInfo.id, userInfo.password, userInfo.name]
      );

      await conn.commit();

      return rows[0];
    } catch (err) {
      await conn.rollback();

      throw err;
    } finally {
      conn.release();
    }
  }
}

export default userStorage;
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.