Skip to main content

Command Palette

Search for a command to run...

Express.js와 MySql기반 서버 구축(SignUp 구축)

Published
•3 min read•View as Markdown

개요

Next.js와 Express.js를 연계하여 도서 대여 서비스를 구축하고자 한다. 로그인 서비스를 구축하고 있으며 오늘은 서버 구축 과정에 대해 이야기해보고자 한다.

Server.js

const express = require('express');
const bodyParser = require('body-parser');

const cors = require('cors');

const loginRouter = require('./routes/auth/login');
const signUpRouter = require('./routes/auth/signup');
const authRouter = require('./routes/auth/auth');
const secretGenerator = require('./secret');

const app = express();
const port = 3001;

secretGenerator.updateSecretKey();

// 주기적으로 실행 (예: 24시간마다)
const interval = 2 * 60 * 60 * 1000; // 24시간
setInterval(secretGenerator.updateSecretKey, interval);

app.use(cors());

app.use(express.urlencoded({ extended: true }));
app.use(bodyParser.json());

// app.post('/auth/login', login.getUserHandler);
app.use('/auth/login', loginRouter);
app.use('/auth/signup', signUpRouter);
app.use('/auth/auth', authRouter);

app.listen(port, () => {
    console.log('Server port: ', port);
});

loginRouter와 signUpRouter를 분리했다.

기본적으로 app.use()로 원하는 라우터에 분리한 라우터 모듈을 분리하여 등록했다. 이중 signUpRouter에 대해 자세히 보자.

signUpRouter

const express = require('express');

const signUpController = require('../../controllers/userSignupController');

const router = express.Router();

router.use((req, res, next) => {
    console.log('sign up process');
    next();
});

router.post('/', signUpController.addUserHandler);

module.exports = router;

라우터를 살펴보면, express.Router()로 라우터를 생성하고, router.post('/', function );를 통해 '/auth/signup'에 signUpController 모듈의 addUserHandler함수를 등록하여, 이 라우터로 post 요청이 들어올 때마다, 이 함수를 실행한다.

signUpController

signUp 과정에서 데이터를 request로 보냈을 때, 데이터를 처리하는 프로세스를 담당한다.

const db = require('../db');
const User = require('../models/user');

exports.addUserHandler = async (req, res) => {
    const userName = req.body.user;
    const studentId = req.body.student_id;
    const password = req.body.password;

    const userData = new User(userName, studentId, password);

    function callback_onAdd(object) {
        res.set('Content-Type', 'application/json');
        if (!object.result) {
            res.send({ message: 'Database failed', result: 0 });
        } else {
            res.send({ message: 'Sign up success', result: 1 });
        }
    }

    function callback_onCheck(object) {
        res.set('Content-Type', 'application/json');
        if (object.isSuccess === 'no data') {
            userData.addUser(callback_onAdd);
        } else if (object.isSuccess === 'log in') {
            res.send({ message: 'You already have account', result: 0 });
        }
    }

    userData.checkUser(callback_onCheck);
};

addUserHandler 함수는 클라이언트에서 request를 보냈을 때, body에서 student_id와 password, username을 얻어낸다. 이는 클라이언트에서 회원가입할 때, 입력하는 정보이다.

checkUser 함수는 user 모델 클래스의 메소드로

    checkUser(cb) {
        let sql = `SELECT * FROM login_data WHERE student_id='${this.student_id}' AND password='${this.password}'`;

        db.query(sql, (err, rows) => {
            if (err) {
                console.log('Error occured during checking user data', err);
                cb({ isSuccess: 'error', id: -1, username: '' });
            } else if (rows.length >= 1) {
                console.log('You log in!');
                cb({
                    isSuccess: 'log in',
                    id: rows[0].id,
                    username: rows[0].user_name,
                });
            } else if (rows.length === 0) {
                console.log('no data please make an account');
                cb({ isSuccess: 'no data', id: -1, username: '' });
            }
        });
    }

mysql 데이터베이스에 SELECT구문으로 모든 데이터를 가져온다. db.query문을 통해 쿼리 결과가 rows에 들어가 콜백함수를 실행한다.콜백 함수의 인자로 쿼리 성공 여부와 쿼리 결과로 얻은 username을 입력한다.

username: rows[0].user_name 에서 rows[0]는 쿼리 결과로 얻는 데이터 중 첫 번째 데이터이므로, 여기서 user_name을 얻을 수 있다.

콜백함수로 실행하는 callback_onCheck(object)

    function callback_onCheck(object) {
        res.set('Content-Type', 'application/json');
        if (object.isSuccess === 'no data') {
            userData.addUser(callback_onAdd);
        } else if (object.isSuccess === 'log in') {
            res.send({ message: 'You already have account', result: 0 });
        }
    }

쿼리결과로 얻는 isSuccess 값에 따라 no data일 때, addUser()를하고, log in일 때, 이미 계정이 있음을 res.send()로 전달한다. addUser()는

    addUser(cb) {
        let sql = `INSERT INTO login_data (user_name, student_id, password) VALUES (?, ?, ?)`;

        db.query(
            sql,
            [this.username, this.student_id, this.password],
            (err, results) => {
                if (err) {
                    cb({
                        message: 'Error occured during adding user data',
                        result: 0,
                    });
                } else {
                    cb({ message: 'Adding account success', result: 1 });
                }
            }
        );
    }
    function callback_onAdd(object) {
        res.set('Content-Type', 'application/json');
        if (!object.result) {
            res.send({ message: 'Database failed', result: 0 });
        } else {
            res.send({ message: 'Sign up success', result: 1 });
        }
    }

addUser는 Insert 구문을 통해 입력한 username, student_id, password로 sql구문을 통해 데이터베이스에 유저데이터를 넣는다. 그리고, 해당 쿼리문 결과에 따라 callback 함수로 callback_onAdd()함수를 실행하여 insert쿼리에 성공했으면, res.send()로 클라이언트에 회원가입을 성공했음을 result에 담아서 보낸다.

More from this blog

[ZSH] tree 사용하기

들어가며 큰 규모의 프로젝트를 출시한 뒤, 후일을 위해서 더 늦기 전에 파일 정리 및 문서화를 진행해야했다. 문서화 작업을 하는 중에 기왕 정리하는 거 파일 구조를 이쁘게 트리 구조로 나열하여 코멘트를 달면 나중에 보더라도 이해하기 더 쉬울 것 같았다. 어떻게 해야 간지나는 트리 구조를 만들 수 있을까 방법을 찾다보니 역시나 파일 구조를 트리로 이쁘게 출력해주는 커맨드 툴이 존재했다. tree 커맨드에 대해서 알아보고 알짜배기 내용만 정리했다....

Feb 21, 20242 min read

[Next.js] parallel routes & intercepting routes

트위터 로그인 모달창을 만들어보며 넥스트의 parallel routes 와 intercepting routes 을 학습한 내용을 정리해보았습니다. 트위터 로그인 창을 확인해봅시다. 루트 디렉토리 화면을 배경으로 i/flow/login 페이지가 동시에 표시되고 있습니다. 저는 app router 를 학습하기 전까지는 createPortal 을 사용하여 포탈 영역에 로그인 컴포넌트를 띄우는 방식을 사용했었습니다. const NoLogin =()=...

Feb 1, 20244 min read

C/C++ 이진 트리(binary tree) 개요 및 구현(1)

개요 트리는 노드들이 나무 가지처럼 연결된 비선형 계층적 자료구조이다. 하위 트리가 존재하고, 그 노드에 또 하위 트리가 존재하는 자료구조 이다. 트리의 맨 위에 있는 루트 노드가 존재한다. 우리가 알아볼 트리는 이진 트리이다. 이진 트리는 자식 노드(부모로부터 아래로 이어진 노드)가 2개 이하인 구조를 말한다. 트리의 사용 사례로는 다음과 같다 계층 적 데이터 저장(파일,폴더) 효율적인 검색 속도 힙 데이터 베이스의 인덱싱 트리에 ...

Jan 31, 20244 min read

[React] Server component (RSC)

React.js 18 에 도입된 리액트 서버 컴포넌트는 서버에서 동작하는 리액트 컴포넌트를 의미합니다. Next가 권장하는 라우팅 방식인 app router의 기반이 되는 컴포넌트이기 때문에 app router 를 이해하기 위해서는 server component 에 대한 이해가 필요합니다. server component 리액트는 클라이언트단만을 컴포넌트화하는 대신, server component라는 개념을 통해 서버 영역을 컴포넌트화합니다. ...

Jan 29, 20243 min read

Flutter, JavaScript

42 posts