[33] Node.js, MVC패턴, CRUD를 이용한 회원가입 예제(1) (로그인, 수정, 탈퇴, 조회)

minjeong·2024년 2월 13일
0
post-thumbnail

MVC 패턴 구조와 함께 회원가입, 로그인, 회원정보 수정, 회원 탈퇴를 DB와 연동하여 구현하는 예제를 풀어보자. 이때, CRUD도 이용해보자.

📌 npm 세팅

  • 터미널에 아래와 같은 내용을 모두 작성해야 이 예제를 실행할 수 있다.
npm init -y
npm i express ejs dotenv cross-env mysql2

만약, nodemon 설치를 이전에 한적이 없다면 이것도 하자!
nodemon : 파일들을 모니터링 하다가 소스코드 변경시 자동으로 node 재실행 하는 패키지

npm i -g nodemon //전역 설치라 한번 설치하면 새로운 파일 생성할때마다 설치안해도 된다.
nodemon -v 

우선, app.js를 만들면서 어떤식으로 만들지 틀을 정했다.

1. app.js

require('dotenv').config(); //환경변수를 위한 모듈
const express = require(express);
const app = express();
const PORT = 8000;

//미들웨어
app.set('view engine', 'ejs');
app.use(express.json());

//router
const indexRouter = require('./routes/Rindex'); //page여는 역할의 페이지
app.use('/', indexRouter);

const userRouter = require('./routes/Ruser'); //CRUD를 포함하고 있는 페이지들의 첫 url
app.use('/api/user', userRouter);

//오류처리
app.get('*', (req, res) => {
    res.status(404).render('404');
});

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

➡️ 초반세팅(미들웨어, 오류처리, 서버연결)은 거의 늘 비슷하고, router만 변경했다.
➡️ indexRouter : 홈페이지를 여는 역할
➡️ userRouter : 클라이언트의 요청 중 /api/user로 시작하는 모든 경우를 처리하고, 사용자 관련 CRUD(Create, Read, Update, Delete) 작업을 수행한다.

2. controller/Cindex.js

📌 Controller: 사용자의 입력을 받아 처리하고, 적절한 Model을 호출하여 데이터를 처리하도록 요청한다. 그리고 Model에서 받은 결과를 View에 전달하여 사용자에게 보여주도록 하는 역할을 한다.

//main 함수 index.ejs 뷰를 렌더링하여 응답을 보내는 역할
exports.main = (req, res) => {
    res.render('index');
};
// 로그인 페이지를 보여주는 역할
exports.login = (req, res) => {
    res.render('login');
};
//회원가입하는 페이지를 보여주는 역할
exports.signUp = (req, res) => {
    res.render('signUp');
};
// 고객 정보 조회(사용자 프로필) 페이지를 보여주는 역할
exports.profile = (req, res) => {
    res.render('profile');
};

➡️ res.render(viewName) : 이 함수는 viewName에 해당하는 뷰를 렌더링하고, 이때 사용되는 템플릿 엔진(예: EJS, Pug 등)에 따라 해당 뷰에 데이터를 삽입하여 HTML을 생성하고 클라이언트에게 보낸다.

3. routes/Rindex.js

  • 클라이언트가 'localhost:8000/~~~' URL로 GET 요청을 보낼 때 해당하는 함수를 호출하도록 설정한다. 예를들어, controller.signUp 함수는 'signUp' 뷰를 렌더링하여 응답을 보낸다.
const express = require('express');
const controller = require('../controller/Cindex');
const router = express.Router();

//localhost:8000/
router.get('/', controller.main);
router.get('/login', controller.login);
router.get('/signUp', controller.signUp);
//각 고객마다 고유의 id를 통해 해당하는 고객 정보를 띄어줘야 하므로 /:id로 생성
router.get('/profile/:id', controller.profile);

//하나의 router만 있더라도 module로 꼭 외부로 내보내야한다.
module.exports = router;

4. routes/Ruser.js

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

//app.js에서 언급했던 것 처럼, Ruser.js는 /localhost:8000/api/user로 시작하는 페이지를 가진다.

//POST /signUp 회원가입(비밀번호가 있으니까 get이 아니라 post방식으로 )
router.post('/signUp', controller.CsignUp);

//POST /login 로그인
router.post('/login', controller.Clogin);

//POST /info 회원정보
router.get('/info/:id', controller.Cinfo);

//PATCH /update 회원수정 , 수정할 땐 방식을 patch 사용
router.patch('/update', controller.Cupdate);

//DELETE /delete 정보삭제
router.delete('/delete', controller.Cdelete);

module.exports = router;

5. controller/Cuser.js

  • 비동기 방식을 위해 async/await를 이용하였다.
const User = require('../model/Muser');

//회원가입
exports.CsignUp = async (req, res) => {
    console.log(res.body); //post방식이므로 res.body로 받아와서 잠시 저장.
    const result = await User.MsignUp(req.body); //model의 Muser에서 쿼리문을 통해 받아온 rows
    console.log('signUp', result);
    res.json({ result: true });
};

//로그인
exports.Clogin = async (req, res) => {
    console.log(req.body);
    const result = await User.Mlogin(req.body);
    console.log('login', result);
    if (result.length >= 1) {
        res.json({ result: true, message: '로그인 성공', data: result[0] }); //프론트에만 보여주는 결과
    } else {
        res.json({ result: false, message: '로그인 실패', id: null }); //프론트에게 이 값이 옳지 않다는 것을 정확하게 알려주기 위해 id를 null로 설정
    }
};

//회원정보 조회
exports.Cinfo = async (req, res) => {
    console.log(req.params.id);
    const result = await User.Minfo(req.params.id);
    console.log('info', result); // 처리가 완료될 때까지 기다린 후 그 결과를 'result'에 저장
    if (result.length > 0) {
        res.json({ result: true, info: result[0], message: '회원존재' });
    } else {
        res.json({ result: false, info: null, message: '존재하지 않는 회원' });
    }
};
//회원정보 수정
exports.Cupdate = async (req, res) => {
    const result = await User.Mupdate(req.body);
    console.log('update', result);
    res.json({ result: true });
};

//회원정보 삭제
exports.Cdelete = async (req, res) => {
    const result = await User.Mdelete(req.body); //body에는 id하나만 받아오게 되는 것
    console.log('delete', result);
    res.json({ result: true });
};

➡️ 따로 모듈로 exports하지않고 함수 실행 즉시 export하였다.
➡️ controller의 역할인 적절한 Model을 호출하여 데이터를 처리하도록 요청하고, Model에서 받은 결과를 View에 전달하여 사용자에게 보여주도록 하였다.(각 기능에 해당하는 함수를 작성)


마무리

model/Muser.js와 프론트에 보이는 views에 들어가는 여러 ejs파일(404.ejs,login.ejs 등), MySQL을 통한 DB생성은 다음 글에서 설명해보겠다.

다음 글(2)
https://velog.io/@sally3921/36-Node.js-MVC%ED%8C%A8%ED%84%B4-CRUD-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-%EC%98%88%EC%A0%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%88%98%EC%A0%95-%ED%83%88%ED%87%B4-%EC%A1%B0%ED%9A%8C

profile
중요한 건 꺾여도 다시 일어서는 마음

0개의 댓글