Nodejs

 

 

패키지 설치(자바 maven)


#npm init

name : (DatabaseExample) database_example

 

-- 모듈 설치

#npm install express --save
#npm install http --save
#npm install path --save

#npm install body-parser --save
#npm install cookie-parser --save
#npm install express-session --save
#npm install express-error-handler --save

#npm install express-error-handler --save

 

mongodb 버전 3.0이상을 사용할 때

버전 차이 주의

 

1.  { useNewUrlParser: true }

 MongoClient.connect(databaseUrl, { useNewUrlParser: true },function(err, db){
        if(err){
            console.log('데이터베이스 연결 시 에러 발생함');
            return;
        }
        
        console.log('데이터베이스에 연결됨 : ' + databaseUrl);
        database=db.db('local'); /*database명을 명시했다.*/

    });

 

 

2.  부제: Node.js Nosql 연동법.

 

 Node.js의 mongodb모듈을 활용하여 mongodb를 연동하는 도중

 

 

 라는 오류를 마주쳤다. 한참을 헤맨 끝에 간단히 해결되었지만, 나같은 고민을 하는 사람들이 더 쉽게 고민을 해결했으면 하는 마음에 삽질로그를 남긴다.

 

 먼저, 내가 간단하게 만들어본 프로그램은 화면에서 id와 password를 입력받아 DB에 존재하는지 검증하고, 로그인 성공여부를 보여주는 기능을 한다. db연동은 아래와 같이 했다. 먼저 DB연결하는 function이다.

 

//
// 기본 모듈 선언 및 미들웨어 선언 생략
var MongoClient = require('mongodb').MongoClient;
var db; // 연결 받아올 변수(중요)
 
function connectDB() {
    var databaseUrl = 'mongodb://localhost:27017/local';
     
    MongoClient.connect(databaseUrl, function(err, database) {
        if(err) throw err;
         
        console.log('데이터베이스에 연결됨: '+databaseUrl);
        db = database; /*이부분 주목*/
    });
}


 

 mongodb 모듈을 사용했다. 그뒤 connect함수로 DB 연결을 시도했다. 당연히, DB연결은 잘 되었다. 아래 코드는 'users' Collection을 가져와 입력값과 비교해보는 function이다.

 

// users collection 비교 function
var authUser = function(database, id, password, callback) {
    var users = database.collection('users');   
    users.find({"id": id, "password": password}).toArray(function(err, docs){
        if(err) {
            callback(err, null);
            return;
        }       
        if(docs.length > 0) {
            // 일치하는 값 찾음.           
        } else {
            // 일치하는 값 없음.
        }
    });
}


 

 내친김에 Router 코드도 소개하겠다.

 

// router function
app.post('/process/login', function(req, res){
     
    var paramId = req.body.id;
    var paramPassword = req.body.password;
     
    if(database) {
        authUser(database, paramId, paramPassword, function(err, docs) {
             
            if(err) throw err;
             
            if(docs) {
                // 결과가 있음. 로그인 성공
            } else {
                // 결과가 없음. 로그인 실패
            }
        });
    } else {
        // db변수가 없음. db연결 오류
    }   
});


 

 별 문제가 없어보였지만, 이 글의 처음에 보여줬던 에러(db.collection is not a function)가 발생했다. 구글링을 해본 결과, 아래와 같은 힌트를 얻었다.

 

 In mongodb version >= 3.0, That database variable is actually the parent object of the object you are trying to access with database.collection('whatever'). To access the correct object, you need to reference your database name, for me that was by doing

 

mongodb 버전 3.0이상을 사용할 때는, connection을 할 때에 database명을 명시해야 한다는 것이다. 그래서 DBConnection 하는 부분을 아래와 같이 바꿔봤다.



 

<p>var MongoClient = require('mongodb').MongoClient;
var db; // 연결 받아올 변수(중요)
 
function connectDB() {
    var databaseUrl = 'mongodb://localhost:27017/local';
     
    MongoClient.connect(databaseUrl, function(err, database) {
        if(err) throw err;
         
        console.log('데이터베이스에 연결됨: '+databaseUrl);
        db = database.db('local'); /*database명을 명시했다.*/
    });
}</p>


 

 위와 같이 database명을 명시해주니 아주 간단하게 해결되었다. mongodb 사용시 버전에 유의하여 사용해야겠다.

출처: https://preamtree.tistory.com/109 [Preamtree의 행복로그]

 

 

app.js

var express =require('express');
var http=require('http');
var static=require('serve-static');
var path=require('path');

var bodyParser=require('body-parser');
var cookieParser=require('cookie-parser');
var session=require('express-session');
//에러 핸들러 모듈 사용
var expressErrorHandler=require('express-error-handler');

//mongodb 모듈 사용
var MongoClient=require('mongodb').MongoClient;


var database;
//데이터베이스 연결
function connectDB(){
    var databaseUrl='mongodb://localhost:27017/local';
    
    MongoClient.connect(databaseUrl, { useNewUrlParser: true },function(err, db){
        if(err){
            console.log('데이터베이스 연결 시 에러 발생함');
            return;
        }   
        console.log('데이터베이스에 연결됨 : ' + databaseUrl);
        database=db.db('local'); /*database명을 명시했다.*/
    });
}

var app=express();

app.set('port', process.env.PORT || 3000);

//미들웨어 등록 시작
app.use('/public', static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

app.use(cookieParser());

//세션 저장
app.use(session({
    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 + ', ' + paramPassword);
    
      if(database){
          console.log("DB 사용자 정보 인증 시작");
          authUser(database, paramId, paramPassword, function(err, docs){
              if(err) {
                  console.log('에러 발생. ');
                  res.writeHead(200, {"Content-Type": "text/html;charset=utf8"});
                  res.write('<h1>에러 발생</h1>');
                  res.end();                  
              }
              
              if(docs){
                  console.dir(docs);
                  res.writeHead(200, {"Content-Type": "text/html;charset=utf8"});
                  res.write('<h1>사용자 로그인 성공</h1>');
                  res.write("<div><p>사용자 : " + docs[0].name +'</p></div>');
                  res.write('<br><br><a href="/public/login.html">다시 로그인하기</a>');
                  res.end();
                  
              }else{
                  console.log('에러 발생. ');
                  res.writeHead(200, {"Content-Type" : "text/html;charset=utf8"});
                  res.write('<h1>사용자 데이터 조회 안됨.</h1>');
                  res.end();            
              }
          });
      }else{

            console.log('에러 발생. ');
            res.writeHead(200, {"Content-Type" : "text/html;charset=utf8"});
            res.write('<h1>데이터베이스 연결 안됨.</h1>');
            res.end();
                  
      }  
    
});


app.use('/', router);


var authUser =function(db, id, password, callback){
    console.log('authUser 호출됨. ');
    console.dir(db);
    var users=db.collection('users');
    
    console.dir(users);
    
    
    users.find({"id":id,  "password":password}).toArray(function(err, docs){
         if(err){
            console.log('error');
            callback(err, null);
             
         }
            
         if(docs.length >0){
            
            console.log('일치하는 사용자를 찾음.');
             callback(null, docs);
         }else{
             console.log('일치하는 사용자를 찾지 못함.');
             callback(null, null);
         }  
    });
    
    
};


//404 에러 페이지 처리
var errorHandler=expressErrorHandler({
    static:{
        '404':'./public/404.html'   
    }
});

app.use(expressErrorHandler.httpError(404));
app.use(errorHandler);



var server=http.createServer(app).listen(app.get('port'), function(){
   console.log('익스프레스로 웹 서버를 실행함 : ' + app.get('port')) ;
   
    connectDB();
    console.dir(database);
});




 

 

404.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>에러</title>
</head>
<body>
    <h3>에러</h3>
    <br>
    <p>요청하신 페이지를 찾을 수 없습니다.</p>
    <br><br>
    <a href="/">돌아가기</a>
</body>    
</html>

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

뇌물을 받고 부정을 저지르는 자가 천하에 가득하건만, 죄는 박복한 사람에게 얽매여 든다. -명심보감

댓글 ( 4)

댓글 남기기

작성

Nodejs 목록    more