본문 바로가기
IT

Day 9

by 깻잎쌈 2020. 2. 2.
반응형

모듈화하기 

스키마 생성과 라우팅 함수를 각각의 파일로 분리하기 

 

router.route('/process~').post(function(req,res){

.....

}

 

-->

var user = require('./routes.user');

router.route('/process~').post(user.login);


app.js

DB연결(connectDB)

-> 사용자 스키마, 모델 정의(createUserSchema)

-> app 객체에 database 속성 추가

var user = require('./routes/user');

var database; 

function createUserSchema() { 
    //스키마 정의 
    database.userSchema = require('./database/user_schema').createSchema(mongoose);  

    //모델 정의  
   database.userModel = mongoose.model("users3", database.userSchema); 
    console.log('user3 모델 정의됨 '); 
}

...

// app 객체에 database 속성 추가 
app.set('database', database);

...

//로그인 라우팅 함수
router.route('/process/login').post(user.login);

//사용자 추가 라우팅 함수 
router.route('/process/adduser').post(user.adduser);
더보기
var express = require('express'),
    http = require('http'),
    path = require('path');

var bodyParser = require('body-parser'),
    static = require('serve-static'),
    expressErrorHandler = require('express-error-handler'),
    cookieParser = require('cookie-parser'),
    expressSession = require('express-session');

var mongoClient = require('mongodb').MongoClient,
    mongodb = require('mongodb'),
    mongoose = require('mongoose');

var crypto = require('crypto');

var app = express();

var user = require('./routes/user');

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

app.use(bodyParser.urlencoded({
    extended: false
}));
app.use(bodyParser.json());
app.use('/public', static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(expressSession({
    secret: 'my key',
    resave: true,
    saveUninitialized: true
}));

var database;
//var userSchema; //database.userSchema
//var userModel;  //database.userModel

function createUserSchema() {
    //스키마 정의
    database.userSchema = require('./database/user_schema').createSchema(mongoose); 

    //모델 정의 
   database.userModel = mongoose.model("users3", database.userSchema);
    console.log('user3 모델 정의됨 ');

}


//db에 연결
function connectDB() {
    //db 연결정보
    var databaseUrl = 'mongodb://localhost:27017/local';

    //db 연결
    console.log('....db에 연결합니다. ');
    //기본 promise(mPromise)를 노드의 promise로 교체
    mongoose.Promise = global.Promise;
    mongoose.connect(databaseUrl);

    database = mongoose.connection;

    //db 연결이 안됬을때 
    database.on('error', console.error.bind(console, 'mongoose 연결 error'));

    //db가 연결됬을때 
    database.on('open', function () {
        console.log('db에 연결됬습니다. :' + databaseUrl);

        // 스키마 및 모델 정의
        createUserSchema();
    });


    //연결이 끊어졌을때  5초 후 다시 연결 
    database.on('disconnected', function () {
        console.log('연결 끊어짐. 5초후 다시 연결합니다');
        setInterval(connectDB, 5000);
    });
    
    
    // app 객체에 database 속성 추가
    app.set('database', database);

}


var router = express.Router();

//로그인 라우팅 함수
router.route('/process/login').post(user.login);

//사용자 추가 라우팅 함수 
router.route('/process/adduser').post(user.adduser);

// 사용자 리스트 라우팅 함수
router.route('/process/listuser').post(user.listuser);


app.use('/', router);

var errorHandler = expressErrorHandler({
    static: {
        '404': './public/404.html'
    }
});

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


app.listen(app.get('port'), function () {
    console.log('Server Started ' + app.get('port'));

    //db연결
    connectDB();
});

 


스키마 정의 

user_schema.js

//userSchema 직접 할당 
module.exports = schema;

더보기
var crypto = require('crypto');

var schema ={};

schema.createSchema = function(mongoose) {

    //스키마 정의
    // password를 hase- 로 변경 
    // 모두 default 속성 추가 
    // salt 속성 추가 
    userSchema = mongoose.Schema({
        id: {
            type: String,
            required: true,
            unique: true,
            'default':' '
        },
        hashed_password: {
            type: String,
            required: true,
            'default': ' '
        },
        salt: {
            type: String,
            required: true
            //default: ' '
        },
        name: {
            type: String,
            index: 'hashed',
            default: ' '
        },
        age: {
            type: Number,
            'default': -1
        },
        created_at: {
            type: Date,
            index: {
                unique: false
            },
            'default': Date.now
        },
        updated_at: {
            type: Date,
            index: {
                unique: false
            },
            'default': Date.now
        }
    });

    // info를 virtual 메소드로 정의
    userSchema
        .virtual('password')
        .set(function (password) {
            //console.log('레레레');
            this._password = password;
            this.salt = this.makeSalt();
            this.hashed_password = this.encryptPassword(password);
            console.log('virtual password set 호출됨 : ' + this.hashed_password);
        })
        .get(function () {
            console.log('virtual password의 get 호출됨.');
            return this._password;
        });
    
    //스키마에 모델 인스턴스에서 사용할 수 있는 메소드 추가
    // 비밀번호 암호화 메소드
    userSchema.method('encryptPassword', function(plainText, inSalt){
        if(inSalt){
            return crypto.createHmac('sha1', inSalt).update(plainText).digest('hex');
        }else{
            return crypto.createHmac('sha1', this.salt).update(plainText).digest('hex');
        }
    });
    
    //salt 값 만들기 
    userSchema.method('makeSalt', function(){
        return Math.round((new Date().valueOf() * Math.random())) + ' ';
    });
    
    // 입력된 비번이랑 비교 (true / false 리턴)
    userSchema.method('authenticate', function(plainText, inSalt, hashed_password){
        if(inSalt){
            console.log('authenticate 호출됨1 : %s => %s : ss %s, %s', plainText, this.encryptPassword(plainText, inSalt), inSalt, hashed_password);
            return this.encryptPassword(plainText, inSalt) === hashed_password;
        }else{
            console.log('authenticate 호출됨2 : %s => %s : %s', plainText, this.encryptPassword(plainText), hashed_password);
            return this.encryptPassword(plainText) === hashed_password;
            
        }
    });
    
    // 필수 속성에 대한 유효성 확인
    userSchema.path('id').validate(function(id){
        return id.length;
    }, 'id 값이 없슴다');
    
    userSchema.path('name').validate(function(name){
        return name.length;
    }, 'name 값이 없슴다');
    
    userSchema.path('hashed_password').validate(function (hashed_password) {
		return hashed_password.length;
	}, 'hashed_password 칼럼의 값이 없습니다.');
    
    
    // 스키마에 static 메소드 추가
    //id 속엉을 전닯망아 검색후 콜백으로 결과 넘겨줌
    userSchema.static('findById', function(id, callback){
        return this.find({id:id}, callback);
    });
    //모든 문서 데이터 반환
    userSchema.static('findAll', function(callback){
        return this.find({}, callback);
    });
    
    
    console.log('user 스키마 정의됨');
    
    return userSchema;

};

//userSchema 직접 할당 
module.exports = schema;

 


라우팅 함수 

routes/user.js

// 데이터베이스 객체 참조
var database = req.app.get('database');

더보기
var adduser = 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;

    console.log('요청 파라미터 : ' + paramId + ', ' + paramPassword + ', ' + paramName);

    // 데이터베이스 객체 참조
	var database = req.app.get('database');
    
    //db 연결됬으면
    if (database) {
        addUser(database, paramId, paramPassword, paramName, function (err, result) {
            if (err) {
                console.log('사용자 추가 중 에러발생' + err.stack);
                res.send('<h2>사용자 추가 중 에러 발생</h2>');
            }

            // 추가된 거 있으면 
            if (result) { // && result.insertedCount >0 ){
                console.log('res11 : ' + result);

                res.writeHead('200', {
                    'Content-Type': 'text/html;charset=utf8'
                });
                res.write('<h1> 사용자 추가 성공 </h1>');
                res.write('<div><p>사용자 id : ' + paramId + '</p></div>');
                res.write('<div><p>사용자 name : ' + paramName + '</p></div>');
                res.end();
                //추가할거 없으면     
            } else {
                console.log('res 22: ' + result);
                res.writeHead('200', {
                    'Content-Type': 'text/html;charset=utf8'
                });
                res.write('<h1> 추가 실패 </h1>');
                res.write("<br><br><a href = '/public/adduser.html'> 사용자 추가하기 </a>");
                res.end();
            }
        });
    } else {
        res.writeHead('200', {
            'Content-Type': 'text/html;charset=utf8'
        });
        res.write('<h1> DB 연결 실패 </h1>');
        res.end();
    }
};


var login = function(req,res){
    console.log('/process/login 호출됨 ');

    var paramId = req.body.id || req.query.id;
    var paramPassword = req.body.password || req.query.password;
    
    // 데이터베이스 객체 참조
	var database = req.app.get('database');

    //db가 연결되었으면
    if (database) {
        authUser(database, paramId, paramPassword, function (err, docs) {
            if (err) {
                console.log(err.stack);
                throw err;
            }

            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>Param id : ' + paramId + '</p></div>');
                res.write('<div><p>Param password : ' + 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();
            }
        });
        //db랑 연결안됬으면
    } else {
        res.writeHead('200', {
            'Content-Type': 'text/html;charset=utf8'
        });
        res.write('<h1> DB 연결 실패 </h1>');
        res.write('<div><p> DB에 연결하지 못했습니다 </p></div>');
        //res.write("<br><br><a href='/public/login.html'> 다시 로그인 </a>");
        res.end();
    }
}

var listuser = function(req,res){
    console.log('/process/listuser 호출됨');
    
    // 데이터베이스 객체 참조
	var database = req.app.get('database');

    // db 연결되면 
    if (database) {
        database.userModel.findAll(function (err, results) {
            if (err) {
                console.log('사용자 리스트 조회중 에러 발생 : ' + err.stack);

                res.writeHead('200', {
                    'Content-Type': 'text/html;charset=utf8'
                });
                res.write('<h1> 사용자 리스트 조회중 에러 발생 </h1>');
                res.write('<p>' + err.stack + '</p');
                res.end();

                return;
            }

            //결과 있으면 
            if (results.length > 0) { // results.length>0 ??
                console.dir(results);

                res.writeHead('200', {
                    'Content-Type': 'text/html;charset=utf8'
                });
                res.write('<h1> 사용자 리스트 </h1>');
                res.write('<div><ul>');

                for (var i = 0; i < results.length; i++) {
                    var curId = results[i]._doc.id;
                    var curName = results[i]._doc.name;
                    res.write('    <li>#' + (i + 1) + ' : ' + curId + ', ' + curName + '</li>');
                }

                res.write('<div><ul>');
                res.end();
                //결과 없으면    
            } else {
                res.writeHead('200', {
                    'Content-Type': 'text/html;charset=utf8'
                });
                res.write('<h1> 사용자 리스트 조회 실패</h1>');
                res.end();
            }
        });
    } else {
        console.log('db 연결 오류 ');
        res.writeHead('200', {
            'Content-Type': 'text/html;charset=utf8'
        });
        res.write('<h1> DB 연결 실패</h1>');
        res.end();
    }
}



// 사용자 인증
var authUser = function (database, id, password, callback) {
    console.log('authUser 함수 호출됨');

    //ID로 검색 
    database.userModel.findById(id, function (err, results) { //database.userModel !!!!!
        if (err) {
            callback(err, null);
            return;
        }

        console.log('ID : %s로 검색 결과 ', id);
        console.log(results);

        if (results.length > 0) {
            console.log('ID와 일치하는 사용자 찾음');
            
            //비밀번호 확인
            var user = new database.userModel({id : id}); //database.userModel
            var authenticated = user.authenticate(password, results[0]._doc.salt, results[0]._doc.hashed_password);
            
            if(authenticated){
                console.log('비밀번호 일치함');
                callback(null, results);
            }else{
                console.log('비밀번호가 일치하지 않음 ');
                callback(null,null);
            }

        } else {
            console.log('ID와 일치하는 사용자 못찾음');
            callback(null, null);
        }
    });

}

// 사용자 추가
var addUser = function (database, id, password, name, callback) {
    console.log('adduser 호출됨 ' + id);

    // userModel 인스턴스 생성
    var user = new userModel({ //database.userModel !!!!!!!
        "id": id,
        "password": password,
        "name": name
    });

    user.save(function (err, user) {
        if (err) {
            callback(err, null);
            return;
        }
        console.log('사용자 데이터 추가함');
        callback(null, user);
    });

}


module.exports.adduser = adduser;
module.exports.login = login;
module.exports.listuser = listuser;

반응형

'IT' 카테고리의 다른 글

Html] CSS 속성  (0) 2020.02.05
Day10  (2) 2020.02.04
Day8  (0) 2020.02.01
Day7 -1  (0) 2020.01.31
Day7  (0) 2020.01.31

댓글