개발일지/✅ 예약 시스템

Node.js와 MySQL을 이용한 로그인/회원가입 예제 (소스코드)

무딘붓 2022. 8. 9. 22:24

Node.js와 MySQL로 구현한 로그인, 회원가입 실행 화면

설명

 

express를 비롯한 Node.js의 모듈들과, 5개 정도의 js파일로 구현한 로그인, 회원가입 예제입니다.

MySQL을 데이터베이스로 사용하였기 때문에 MySQL을 설치하셔야 사용 가능합니다. (사용방법 링크

 

사용하시면서 궁금하신 점이나 문제점이 있다면 댓글 달아주세요.


필요 모듈

 

1. mysql2

2. express

3. express-session

4. session-file-store

5. body-parser

 

npm을 이용하여 다운로드하시면 됩니다.

 

mysql2 대신 mysql 모듈을 사용하셔도 무방하며,

session-file-store 모듈은 세션을 다른 방식으로 저장하실 경우 사용하지 않으셔도 됩니다.

body-parser 역시 편의를 위한 것으로, 소스코드에서 request.body 부분만 수정하시고 사용하셔도 됩니다.


MySQL 세팅

 

사용을 원하시는 database에서 아래와 같이 테이블을 만들어 주시면 됩니다.

MySQL이 익숙하지 않으시면 링크 를 참고해주세요

CREATE TABLE userTable (
  id int(12) NOT NULL AUTO_INCREMENT,
  username varchar(50) NOT NULL,
  password varchar(255) NOT NULL,
  PRIMARY KEY(id)
) charset=utf8;

Main.js

const express = require('express')
const session = require('express-session')
const bodyParser = require('body-parser');
const FileStore = require('session-file-store')(session)

var authRouter = require('./lib_login/auth');
var authCheck = require('./lib_login/authCheck.js');
var template = require('./lib_login/template.js');

const app = express()
const port = 3000

app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
  secret: '~~~',	// 원하는 문자 입력
  resave: false,
  saveUninitialized: true,
  store:new FileStore(),
}))

app.get('/', (req, res) => {
  if (!authCheck.isOwner(req, res)) {  // 로그인 안되어있으면 로그인 페이지로 이동시킴
    res.redirect('/auth/login');
    return false;
  } else {                                      // 로그인 되어있으면 메인 페이지로 이동시킴
    res.redirect('/main');
    return false;
  }
})

// 인증 라우터
app.use('/auth', authRouter);

// 메인 페이지
app.get('/main', (req, res) => {
  if (!authCheck.isOwner(req, res)) {  // 로그인 안되어있으면 로그인 페이지로 이동시킴
    res.redirect('/auth/login');
    return false;
  }
  var html = template.HTML('Welcome',
    `<hr>
        <h2>메인 페이지에 오신 것을 환영합니다</h2>
        <p>로그인에 성공하셨습니다.</p>`,
    authCheck.statusUI(req, res)
  );
  res.send(html);
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

express로 서버를 실행시키는 main.js 파일입니다. 

 

각 페이지의 세부 구현은 lib_login 폴더에 있는 파일에 저장되어 있으며, 경로의 수정을 원하는 경우 바꿔서 사용하시면 됩니다.

 

페이지의 root 에 접속했을 때 세션을 확인해서 로그인 되어있으면 /main 페이지로, 아니면 /auth/login 페이지로 리다이렉션 시킵니다.

 

 /main 페이지 내용은 간단하게 해당 파일에 작성되어있으며, 각종 인증관련 페이지는 /auth/ 경로를 통해 접속합니다.


db.js

var mysql = require('mysql2');
var db = mysql.createConnection({
    host: '',
    user: '',
    password: '',
    database: ''
});
db.connect();

module.exports = db;

MySQL에 접속하기 위한 정보를 담고 있는 db.js 파일입니다. mysql2 모듈을 사용하고 있으나 mysql 모듈을 사용하셔도 변경하실 내용은 없습니다. 자신이 원하는 대로 host, user, password, database의 내용을 채워서 사용하시면 됩니다.


auth.js

var express = require('express');
var router = express.Router();

var template = require('./template.js');
var db = require('./db');

// 로그인 화면
router.get('/login', function (request, response) {
    var title = '로그인';
    var html = template.HTML(title,`
            <h2>로그인</h2>
            <form action="/auth/login_process" method="post">
            <p><input class="login" type="text" name="username" placeholder="아이디"></p>
            <p><input class="login" type="password" name="pwd" placeholder="비밀번호"></p>
            <p><input class="btn" type="submit" value="로그인"></p>
            </form>            
            <p>계정이 없으신가요?  <a href="/auth/register">회원가입</a></p> 
        `, '');
    response.send(html);
});

// 로그인 프로세스
router.post('/login_process', function (request, response) {
    var username = request.body.username;
    var password = request.body.pwd;
    if (username && password) {             // id와 pw가 입력되었는지 확인
        
        db.query('SELECT * FROM usertable WHERE username = ? AND password = ?', [username, password], function(error, results, fields) {
            if (error) throw error;
            if (results.length > 0) {       // db에서의 반환값이 있으면 로그인 성공
                request.session.is_logined = true;      // 세션 정보 갱신
                request.session.nickname = username;
                request.session.save(function () {
                    response.redirect(`/`);
                });
            } else {              
                response.send(`<script type="text/javascript">alert("로그인 정보가 일치하지 않습니다."); 
                document.location.href="/auth/login";</script>`);    
            }            
        });

    } else {
        response.send(`<script type="text/javascript">alert("아이디와 비밀번호를 입력하세요!"); 
        document.location.href="/auth/login";</script>`);    
    }
});

// 로그아웃
router.get('/logout', function (request, response) {
    request.session.destroy(function (err) {
        response.redirect('/');
    });
});


// 회원가입 화면
router.get('/register', function(request, response) {
    var title = '회원가입';    
    var html = template.HTML(title, `
    <h2>회원가입</h2>
    <form action="/auth/register_process" method="post">
    <p><input class="login" type="text" name="username" placeholder="아이디"></p>
    <p><input class="login" type="password" name="pwd" placeholder="비밀번호"></p>    
    <p><input class="login" type="password" name="pwd2" placeholder="비밀번호 재확인"></p>
    <p><input class="btn" type="submit" value="제출"></p>
    </form>            
    <p><a href="/auth/login">로그인화면으로 돌아가기</a></p>
    `, '');
    response.send(html);
});
 
// 회원가입 프로세스
router.post('/register_process', function(request, response) {    
    var username = request.body.username;
    var password = request.body.pwd;    
    var password2 = request.body.pwd2;

    if (username && password && password2) {
        
        db.query('SELECT * FROM usertable WHERE username = ?', [username], function(error, results, fields) { // DB에 같은 이름의 회원아이디가 있는지 확인
            if (error) throw error;
            if (results.length <= 0 && password == password2) {     // DB에 같은 이름의 회원아이디가 없고, 비밀번호가 올바르게 입력된 경우 
                db.query('INSERT INTO usertable (username, password) VALUES(?,?)', [username, password], function (error, data) {
                    if (error) throw error2;
                    response.send(`<script type="text/javascript">alert("회원가입이 완료되었습니다!");
                    document.location.href="/";</script>`);
                });
            } else if (password != password2) {                     // 비밀번호가 올바르게 입력되지 않은 경우
                response.send(`<script type="text/javascript">alert("입력된 비밀번호가 서로 다릅니다."); 
                document.location.href="/auth/register";</script>`);    
            }
            else {                                                  // DB에 같은 이름의 회원아이디가 있는 경우
                response.send(`<script type="text/javascript">alert("이미 존재하는 아이디 입니다."); 
                document.location.href="/auth/register";</script>`);    
            }            
        });

    } else {        // 입력되지 않은 정보가 있는 경우
        response.send(`<script type="text/javascript">alert("입력되지 않은 정보가 있습니다."); 
        document.location.href="/auth/register";</script>`);
    }
});

module.exports = router;

인증과 관련된 작업을 처리하는 auth.js파일입니다. /auth/ 경로로 접속하는 페이지는 이 파일에서 관리합니다.

mysql을 이용해서 데이터베이스에 접근해 로그인 과정을 처리하며, 회원가입 과정도 처리합니다.


authCheck.js

module.exports = {
    isOwner: function (request, response) {
      if (request.session.is_logined) {
        return true;
      } else {
        return false;
      }
    },
    statusUI: function (request, response) {
      var authStatusUI = '로그인후 사용 가능합니다'
      if (this.isOwner(request, response)) {
        authStatusUI = `${request.session.nickname}님 환영합니다 | <a href="/auth/logout">로그아웃</a>`;
      }
      return authStatusUI;
    }
  }

로그인 여부를 확인해서 실행하는 함수를 모아 분리한 authCheck.js 파일입니다.


template.js

module.exports = {
  HTML: function (title, body, authStatusUI) {
    return `
    <!doctype html>
    <html>
    <head>    
      <title>Login TEST - ${title}</title>
      <meta charset="utf-8">
      <style>
        @import url(http://fonts.googleapis.com/earlyaccess/notosanskr.css);

        body {
            font-family: 'Noto Sans KR', sans-serif;
            background-color: #AAA2C2;
            margin: 50px;

        }

        .background {
            background-color: white;
            height: auto;
            width: 90%;
            max-width: 450px;
            padding: 10px;
            margin: 0 auto;
            border-radius: 5px;
            box-shadow: 0px 40px 30px -20px rgba(0, 0, 0, 0.3);
            text-align: center;
        }

        form {
            display: flex;
            padding: 30px;
            flex-direction: column;
        }

        .login {
            border: none;
            border-bottom: 2px solid #D1D1D4;
            background: none;
            padding: 10px;
            font-weight: 700;
            transition: .2s;
            width: 75%;
        }
        .login:active,
        .login:focus,
        .login:hover {
            outline: none;
            border-bottom-color: #6A679E;
        }

        .btn {            
            border: none;
            width: 75%;
            background-color: #6A679E;
            color: white;
            padding: 15px 0;
            font-weight: 600;
            border-radius: 5px;
            cursor: pointer;
            transition: .2s;
        }
        .btn:hover {
            background-color: #595787;
        }
    </style>
    </head>
    <body>
      <div class="background">
        ${authStatusUI}
        ${body}
      </div>
    </body>
    </html>
    `;
  }
}

페이지의 디자인과 구조를 저장하고 있는 template.js 파일입니다. 간단한 디자인을 <style></style>에 담고 있으나, 해당 부분은 지워버려도 작동에는 지장이 없습니다.


위 파일들을 다 작성하신 다음, main.js파일을 실행하시면 됩니다.

 

 

 

이 소스코드는 생활코딩 WEB4 - Express Session & Auth 강의 내용을 기반으로 작성되었습니다.

이해가 안 되는 부분이 있거나 개선하고 싶은 점이 있으면 아래 강의를 확인하시면 됩니다.

https://opentutorials.org/module/3648

 

WEB4 - Express-Session-Auth

수업소개 이 수업은 Node.js 웹프래임웍인 Express에서 Session을 이용해 인증을 구현하는 방법을 알려드리는 수업입니다.  수업대상 로그인/로그아웃/접근제한과 같은 인증 기능을 구현하고 싶은 분

opentutorials.org

 

그 외에 MySQL, Express 등에 대해서는 제가 작성한 포스트를 참고하셔도 좋습니다.

(부정확한 내용이 많아 권장하지는 않습니다)

 

[Node.js] 1. 소개 및 설치방법

 

[Node.js] 1. 소개 및 설치방법

Node.js란? 크롬 V8 엔진 (오픈 소스 JavaScript 엔진)을 이용해 브라우저 밖에서 JavaScript로 서버 구축 등의 작업을 가능하게 하는 소프트웨어 플랫폼이다. Web Browser의 기능을 HTML문법으로 불러와 Web Ap

sirius7.tistory.com

[Node.js] 3. 모듈 만들기, 불러오기 (export, require)

 

[Node.js] 3. 모듈 만들기, 불러오기 (export, require)

모듈이란? Node.js으로 앱을 개발하기 위해서는 모듈 시스템을 사용한다. 이때, 모듈이란 ‘미리 만들어둔 함수들의 집합’이라고 할 수 있다. Node.js에서의 모듈은 2가지(코어 모듈, 파일 모듈)

sirius7.tistory.com

[Node.js] 10. MySQL 연동

 

[Node.js] 10. MySQL 연동

생활코딩 Node.js - MySQL 강의를 듣고 공부한 내용을 정리한 게시글입니다. mysql 모듈 설치 npm install -S mysql -S는 --save로 바꿔 써도 된다. 이것은 package.json의 "dependencies" 부분에 설치된 모듈..

sirius7.tistory.com

[Express] 1. 설치방법과 라우팅

 

[Express] 1. 설치방법과 라우팅

Express란? Express는 Node.js를 위한 빠르고 개방적인 간결한 웹 프레임워크 이다.(공식 홈페이지 설명) 그럼 프레임워크(framework)란 무엇인가? 프레임워크는 라이브러리를 포함하는 상위 개념으로, 무

sirius7.tistory.com

[Node.js] 12. 세션(Session)

 

[Node.js] 12. 세션(Session)

세션(Session)이란? 간단히 말하면 쿠키보다 더 안전하게 데이터를 저장하는 방식이다. 쿠키는 브라우저에 저장되는 반면 세션은 데이터를 웹 서버에 저장한다. 세션은 각 클라이언트에 부여한 고

sirius7.tistory.com