Skip to main content

Command Palette

Search for a command to run...

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

Updated
3 min read

개요

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