MongoDB

[MongoDB] - Mongoose 이용하여 데이터 삭제하기 (5)

Riucc 2018. 11. 24. 16:33

Mongoose 이용하여 데이터 삭제하기 (5)

 

// app.js - (4)에서 추가된 내용만 '// ---------' 으로 표시


// Express 기본 모듈 불러오기
var express = require('express')
, http = require('http')
, path = require('path');

// Express의 미들웨어 불러오기
var static = require('serve-static')
var bodyParser = require('body-parser')

// mongoose 모듈 사용
var mongoose = require('mongoose');

// 익스프레스 객체 생성
var app = express()

// 기본 속성 설정
app.set('port', process.env.PORT || 3000);
// public 폴더를 static으로 오픈
app.use('/public', static(path.join(__dirname, 'public')));
// body-parser를 이용해 application/x-www-form-urlencoded 파싱
app.use(bodyParser.urlencoded({ extended: false }))
// body-parser를 이용해 application/json 파싱
app.use(bodyParser.json())

//===== 데이터베이스 연결 =====//
// 데이터베이스 객체를 위한 변수 선언
var database;
// 데이터베이스 스키마 객체를 위한 변수 선언
var UserSchema;
// 데이터베이스 모델 객체를 위한 변수 선언
var UserModel;

//데이터베이스에 연결
function connectDB() {
// 데이터베이스 연결 정보
// localhost:기본포트/데이터베이스명
    var databaseUrl = 'mongodb://localhost:27017/test';
    
    // 데이터베이스 연결
console.log('데이터베이스 연결을 시도합니다.');
// mongoose의 Promise 객체는 global의 Promise 객체 사용하도록 함
mongoose.Promise = global.Promise;
    mongoose.connect(databaseUrl, { useNewUrlParser: true });
    database = mongoose.connection;
    
    database.on('error', console.error.bind(console, 'mongoose connection error.'));    
    database.on('open', function () {
        console.log('데이터베이스에 연결되었습니다. : ' + databaseUrl);
        
        // 스키마 정의
        UserSchema = mongoose.Schema({
            email: String,
            password: String
        }, {versionKey: false}); // __v 삭제위해
        console.log('UserSchema 정의함.');
// 스키마에 static으로 findAll 메소드 추가
        UserSchema.static('findAll', function(callback) {
            return this.find({}, callback);
        });
        
        // UserModel 모델 정의
        UserModel = mongoose.model("users", UserSchema);
        console.log('UserModel 정의함.');
    });
// 연결 끊어졌을 때 5초 후 재연결
    database.on('disconnected', function() {
console.log('연결이 끊어졌습니다. 5초 후 재연결합니다.');
setInterval(connectDB, 5000);
});
}

//===== 라우팅 함수 등록 =====//

// 회원가입 데이터베이스
app.post('/process/signup', function(req,res) {
console.log('/process/signup 호출됨.');
    // 요청 파라미터 확인
var paramEmail = req.body.email || req.query.email;
var paramPassword = req.body.psw || req.query.psw;
console.log('요청 파라미터 : ' + paramEmail + ', ' + paramPassword);
// 데이터베이스 객체가 초기화된 경우, addUser 함수 호출하여 사용자 추가
    if (database) {
        addUser(database, paramEmail, paramPassword, function(err, addedUser) {
if (err) {throw err;}
// 결과 객체 있으면 성공 응답 전송
            if (addedUser) {
                console.dir(addedUser);
                res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
                res.write('<h2>사용자 추가 성공</h2>');
res.end();
} else { // 결과 객체가 없으면 실패 응답 전송
                res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
                res.write('<h2>사용자 추가 실패</h2>');
                res.end();
            }
});
} else { // 데이터베이스 객체가 초기화되지 않은 경우 실패 응답 전송
        res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
        res.write('<h2>데이터베이스 연결 실패</h2>');
        res.end();
    }

});

//사용자를 추가하는 함수
var addUser = function(database, email, password, callback) {
    console.log('addUser 호출됨 : ' + email + ', ' + password);
    
    // UserModel 인스턴스 생성
    var user = new UserModel({"email":email, "password":password});

    // save()로 저장 : 저장 성공 시 addedUser 객체가 파라미터로 전달됨
    user.save(function(err, addedUser) {
        if (err) {
            callback(err, null);
            return;
        }
        
     console.log("사용자 데이터 추가함.");
     callback(null, addedUser);
    
    });
};

// 로그인 라우팅 함수 - 데이터베이스의 정보와 비교
app.post('/process/login', function(req, res) {
    console.log('/process/login 호출됨.');

    // 요청 파라미터 확인
var paramEmail = req.body.email || req.query.email;
var paramPassword = req.body.psw || req.query.psw;
    
console.log('요청 파라미터 : ' + paramEmail + ', ' + paramPassword);

// 데이터베이스 객체가 초기화된 경우, authUser 함수 호출하여 사용자 인증
    if (database) {
        authUser(database, paramEmail, paramPassword, function(err, docs) {
            // 에러 발생 시, 클라이언트로 에러 전송
            if (err) {
console.error('로그인 중 에러 발생 : ' + err.stack);
res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
                res.write('<h2>로그인 중 에러 발생</h2>');
res.write('<p>' + err.stack + '</p>');
                res.end();
return;
}
            
// 조회된 레코드가 있으면 성공 응답 전송
            if (docs) {
                console.dir(docs);

// 조회 결과에서 사용자 이름 확인
                // var username = docs[0].name;
                
                res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
                res.write('<h1>로그인 성공</h1>');
                res.write('<div><p>사용자 이메일 : ' + paramEmail + '</p></div>');
                res.write('<div><p>사용자 패스워드 : ' + paramPassword + '</p></div>');
                res.write("<br><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('<div><p>아이디와 패스워드를 다시 확인하십시오.</p></div>');
                res.write("<br><br><a href='/public/login.html'>다시 로그인하기</a>");
                res.end();
            }
        });
    } else { // 데이터베이스 객체가 초기화되지 않은 경우 실패 응답 전송
        res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
        res.write('<h2>데이터베이스 연결 실패</h2>');
        res.write('<div><p>데이터베이스에 연결하지 못했습니다.</p></div>');
        res.end();
    }
});


// 사용자를 인증하는 함수 : 이메일로 먼저 찾고 비밀번호를 그 다음에 비교하도록 함
var authUser = function(database, email, password, callback) {
    console.log('authUser 호출됨 : ' + email + ', ' + password);
    
    // 1. 이메일과 패스워드 동시 검색
    // UserModel.find({"email":email, "password":password}, function(err, results)
// 1. 이메일을 이용해 검색
    UserModel.find({"email":email}, function(err, results) {
        if (err) {
            callback(err, null);
            return;
        }

        console.log('email [%s]로 사용자 검색결과', email);
        // console.log('email [%s], 패스워드 [%s]로 사용자 검색결과', email, password);
        console.dir(results);
        
        if (results.length > 0) {
            console.log('email과 일치하는 사용자 찾음.');
            
            // 2. 패스워드 확인
            if (results[0]._doc.password === password) {
                console.log('비밀번호 일치함');
                callback(null, results);
            } else {
                console.log('비밀번호 일치하지 않음');
                callback(null, null);
            }
        } else {
         console.log("email과 일치하는 사용자를 찾지 못함.");
         callback(null, null);
     }
    });
}


//사용자 리스트 함수
app.post('/process/listuser', function(req,res) {
    console.log('/process/listuser 호출됨.');

// 데이터베이스 객체가 초기화된 경우, 모델 객체의 findAll 메소드 호출
    if (database) {
        // 1. 모든 사용자 검색
        UserModel.findAll(function(err, results) {
            // 에러 발생 시, 클라이언트로 에러 전송
            if (err) {
console.error('사용자 리스트 조회 중 에러 발생 : ' + err.stack);
res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
                res.write('<h2>사용자 리스트 조회 중 에러 발생</h2>');
res.write('<p>' + err.stack + '</p>');
                res.end();
return;
}
            
            if (results) { // 결과 객체 있으면 리스트 전송
                console.dir(results);
                res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
                res.write('<h2>사용자 리스트</h2>');
                res.write('<div><ul>');
                
                for (var i = 0; i < results.length; i++) {
                    var curEmail = results[i]._doc.email;
                    var curPassword = results[i]._doc.password;
                    res.write(' <li>#' + i + ' : ' + curEmail +
', ' + curPassword + '</li>');
                }   
            
                res.write('</ul></div>');
                res.end();
            } else { // 결과 객체가 없으면 실패 응답 전송
                res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
                res.write('<h2>사용자 리스트 조회 실패</h2>');
                res.end();
            }
        });
    } else { // 데이터베이스 객체가 초기화되지 않은 경우 실패 응답 전송
        res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
        res.write('<h2>데이터베이스 연결 실패</h2>');
        res.end();
    }
    
});



//사용자 패스워드 수정 함수
app.post('/process/update', function(req,res) {
    var userEmail = req.body.email;
    var userPassword = req.body.psw;
    console.log('/process/update 호출됨.');

    if (database) {
        // 아이디로 사용자 검색
        UserModel.findOneAndUpdate({email : userEmail},
{ $set: { password : userPassword }},
{ returnNewDocument: true}, function(err, results) {
            // 에러 발생 시, 클라이언트로 에러 전송
            if (err) {
                console.error('수정 중 에러 발생 : ' + err.stack);
                throw err;
            }
            if (results) {
                console.log(results);
                res.send(userEmail + '의 패스워드 수정 완료');
            }
        });
    }
});

// --------------------------------------------------------------------------
//사용자 패스워드 삭제 함수
app.post('/process/delete', function(req,res) {
    var userEmail = req.body.email;
    console.log('/process/delete 호출됨.');

    // 데이터베이스 객체가 초기화된 경우
    if (database) {
        UserModel.deleteOne({email : userEmail}, function(err, results) {
            // 에러 발생 시, 클라이언트로 에러 전송
            if (err) {
                console.error('삭제 중 에러 발생 : ' + err.stack);
                throw err;
            }
            // 결과 발생 시, 데이터 전송
            if (results) {
                console.log(results);
                res.send(userEmail + '의 이메일 삭제 완료');
            }
        });
    }
});
// --------------------------------------------------------------------------


//===== 서버 시작 =====//

// 프로세스 종료 시에 데이터베이스 연결 해제
process.on('SIGTERM', function () {
console.log("프로세스가 종료됩니다.");
app.close();
});

app.on('close', function () {
    console.log("Express 서버 객체가 종료됩니다.");
    if (database) {
        database.close();
    }
});

// Express 서버 시작
http.createServer(app).listen(app.get('port'), function(){
console.log('서버가 시작되었습니다. 포트 : ' + app.get('port'));

// 데이터베이스 연결을 위한 함수 호출
connectDB();
});


// /public/delete.html


<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>이메일 삭제</title>
    </head>
<body>
    <h1>이메일 삭제</h1>
    <br>
    <form method="post" action="/process/delete">
        <table>
            <tr>
                <td><label>이메일</label></td>
                <td><input type="text" name="email" ></td>
            </tr>
        </table>
        <input type="submit" value="전송" >
    </form>
</body>
</html>