[Node.js] 몽고디비 - 익스프레스에서 사용하기 (회원가입 구현)

MongoDB, Express로 사용자 추가 기능 구현하기

이전 포스팅(로그인 구현)에 이어 사용자 추가(회원가입)를 구현해보자. 로그인 구현에 사용했던 함수에서 크게 벗어나지 않는다. 객체에 추가하는 메소드와 추가된 결과를 확인할 방법만 안다면 쉬울 것이다.

우선 public 폴더에 adduser.html을 만든다.

/public/adduser.html
<!DOCTYPE HTML>
<html>
 
<head>
    <meta charset="UTF-8">
    <title>회원가입</title>
</head>
 
<body>
    <h1>회원가입</h1>
    <br>
    <form method="post" action="/process/adduser">
        <table>
            <tr>
                <td><label>아이디</label></td>
                <td><input type="text" name="id"></td>
            </tr>
            <tr>
                <td><label>비밀번호</label></td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td><label>이름</label></td>
                <td><input type="text" name="name"></td>
            </tr>
        </table>
        <input type="submit" value="전송" name="">
    </form>
</body>
 
</html>
cs

이제 app.js로 넘어와서,
사용자 추가에 대한 함수는 다음과 같다.

var addUser = function(db, id, password, name, callback){
    console.log('addUser 호출됨: ' + id + ', ' + password + ', ' + name);
    
    var users = db.collection('users');
    users.insertMany([{"id": id, "password": password, "name"name}], function(err, result){
        if(err){
            callback(err, null);
            return;
        }
        
        if(result.insertedCount > 0){
            console.log('사용자 추가됨: ' + result.insertedCount);
        } else{
            console.log('추가된 레코드 없음');
        }
        callback(null, result);
    });
}
cs

insertMany() 메소드로 users 객체에 도큐먼트를 추가하고 추가 결과는 콜백 파라미터 result에서 insertedCount로 확인한다. insertedCount 속성은 추가된 레코드의 개수를 알려준다. 조회 함수와 달라진 것은 이것뿐이다.

이제 사용자 추가에 대한 라우터를 정의해보자.

//사용자 추가 라우터
router.route('/process/adduser').post(function(req, res){
    console.log('/process/adduser 호출됨');
    
    var paramId = req.body.id || req.query.id;
    var paramPassword = req.body.password || req.query.password;
    var paramName = req.body.name || req.query.name;
    
    if(database){
        addUser(database, paramId, paramPassword, paramName, function(err, result){
            if(err) throw err;
            if(result && result.insertedCount > 0){
                console.dir(result);
                res.writeHead(200, {
                    "Content-Type""text/html;charset=utf8"
                });
                res.write('<h1>사용자 추가 성공</h1><hr>');
                res.write('<p>name: ' + paramName + '</p>');
                res.write('<br><a href="/public/login.html">다시 로그인 </a>');
                res.end();
            } else{
                res.writeHead(200, {
                    "Content-Type""text/html;charset=utf8"
                });
                res.write('<h1>사용자 추가 실패<h1>');
                res.write('<br><a href="/public/login.html">다시 로그인 </a>');
                res.end();
            }
        });
    } else{
        res.writeHead(200, {
            "Content-Type""text/html;charset=utf8"
        });
        res.write('<h1>DB 연결 실패<h1>');
        res.write('<br><a href="/public/login.html">재접속</a>');
        res.end();
    }
});
cs

코드가 길어보이지만 각 경우에 따른 html 형식의 출력때문에 길어진 것 뿐이다. 사용자 조회 라우터에서 paramName 변수만 추가되었고, 나머지 형식은 같다. addUser() 메소드를 호출해서 result가 존재하는지에 따라 출력을 정의한다.

이제 회원가입도 몽고디비를 통해 익스프레스에서 구현해보았다. 회원가입, 로그인이 모두 구현된 app.js는 다음과 같다.

var express = require('express'),
    http = require('http'),
    path = require('path'),
    bodyParser = require('body-parser'),
    cookieParser = require('cookie-parser'),
    static = require('serve-static'),
    errorHandler = require('errorhandler'),
    expressErrorHandler = require('express-error-handler'),
    expressSession = require('express-session'),
    MongoClient = require('mongodb').MongoClient;
 
//DB 객체를 위한 변수선언
let database;
 
//DB 연결
function connectDB() {
    const databaseUrl = 'mongodb://localhost:27017';
 
    MongoClient.connect(databaseUrl, {useNewUrlParser: true, useUnifiedTopology: true}, function(err, client) {
        if (err) throw err;
 
        console.log('DB 연결됨 : ' + databaseUrl);
        //database 변수에 할당
        let db = client.db("local");
        database = db
    })
}
 
var app = express();
 
app.set('port', process.env.PORT || 3000);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use('/public', express.static(__dirname + '/public'));
app.use(cookieParser());
app.use(expressSession({
    secret: 'my key',
    resave: true,
    saveUninitialized: true
}));
 
var router = express.Router();
 
//로그인 처리 라우터
router.route('/process/login').post(
    function (req, res) {
        console.log('process/login 호출됨');
        var paramId = req.body.id || req.query.id;
        var paramPassword = req.body.password || req.query.password;
        console.log('paramId : ' + paramId + ', paramPW : ' + paramPassword);
        if (database) {
            authUser(database, paramId, paramPassword,
                function (err, docs) {
                    if (err) {
                        console.log('Error!');
                        res.writeHead(200, {
                            "Content-Type""text/html;charset=utf8"
                        });
                        res.write('<h1>에러발생</h1>');
                        res.end();
                        return;
                    }
 
                    if (docs) {
                        console.dir(docs);
                        res.writeHead(200, {
                            "Content-Type""text/html;charset=utf8"
                        });
                        res.write('<h1>로그인 성공</h1><hr>');
                        res.write(docs[0].id + '/' + docs[0].name);
                        res.write('<br><a href="/public/login.html">다시 로그인 </a>');
                        res.end();
 
                    } else {
                        console.log('Error(empty)');
                        res.writeHead(200, {
                            "Content-Type""text/html;charset=utf8"
                        });
                        res.write('<h1>사용자 없음</h1><hr>');
                        res.write('<a href="/public/login.html">다시 로그인</a>');
                        res.end();
                    }
                });
        } else {
            console.log('DB 연결 안됨');
            res.writeHead(200, {
                "Content-Type""text/html;charset=utf8"
            });
            res.write('<h1>데이터베이스 연결 안됨</h1>');
            res.end();
        }
    }
);
 
//사용자 추가 라우터
router.route('/process/adduser').post(function(req, res){
    console.log('/process/adduser 호출됨');
    
    var paramId = req.body.id || req.query.id;
    var paramPassword = req.body.password || req.query.password;
    var paramName = req.body.name || req.query.name;
    
    if(database){
        addUser(database, paramId, paramPassword, paramName, function(err, result){
            if(err) throw err;
            if(result && result.insertedCount > 0){
                console.dir(result);
                res.writeHead(200, {
                    "Content-Type""text/html;charset=utf8"
                });
                res.write('<h1>사용자 추가 성공</h1><hr>');
                res.write('<p>name: ' + paramName + '</p>');
                res.write('<br><a href="/public/login.html">다시 로그인 </a>');
                res.end();
            } else{
                res.writeHead(200, {
                    "Content-Type""text/html;charset=utf8"
                });
                res.write('<h1>사용자 추가 실패<h1>');
                res.write('<br><a href="/public/login.html">다시 로그인 </a>');
                res.end();
            }
        });
    } else{
        res.writeHead(200, {
            "Content-Type""text/html;charset=utf8"
        });
        res.write('<h1>DB 연결 실패<h1>');
        res.write('<br><a href="/public/login.html">재접속</a>');
        res.end();
    }
});
 
app.use('/', router);
 
//사용자 조회 함수
var authUser = function (db, id, password, callback) {
    console.log("authUser 호출됨");
 
    var users = db.collection('users');
    var result = users.find({
        "id": id,
        "password": password
    });
    result.toArray(
        function (err, docs) {
            if (err) {
                callback(err, null);
                return;
            }
            if (docs.length > 0) {
                console.log('아이디 [%s], 비밀번호 [%s] 일치 사용자 찾음', id, password);
                callback(null, docs);
            } else {
                console.log('일치 사용자 없음');
                callback(nullnull);
            }
        });
}
 
//사용자 추가 함수
var addUser = function(db, id, password, name, callback){
    console.log('addUser 호출됨: ' + id + ', ' + password + ', ' + name);
    
    var users = db.collection('users');
    users.insertMany([{"id": id, "password": password, "name"name}], function(err, result){
        if(err){
            callback(err, null);
            return;
        }
        
        if(result.insertedCount > 0){
            console.log('사용자 추가됨: ' + result.insertedCount);
        } else{
            console.log('추가된 레코드 없음');
        }
        callback(null, result);
    });
}
 
// 404 에러 페이지 처리
var errorHandler = expressErrorHandler({
    static: {
        '404''./public/404.html'
    }
});
 
app.use(expressErrorHandler.httpError(404));
app.use(errorHandler);
 
//웹서버 생성
var appServer = http.createServer(app);
appServer.listen(app.get('port'),
    function () {
        console.log('express server started with port ' + app.get('port'));
        connectDB(); //DB 연결 , DB 연결 먼저해도 상관 없음
    }
);
 
cs


댓글 없음:

Powered by Blogger.