반응형
비밀번호 암호화해서 저장
password를 virtual 메소드로 정의하기에 몽고디비에는 비번값이 저장되지 않는다.
대신 해쉬처리된 비번이 저장된다.
addUser 함수의 save() 메소드를 통해 비밀번호가 암호화되서 hashed_password로 저장
var user = new userModel({
"id": id,
"password": password,
"name": name
});
user.save(function (err, user) {
if (err) {
callback(err, null);
return;
}
console.log('사용자 데이터 추가함');
callback(null, user);
});
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();
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;
var userModel;
function createUserSchema() {
//스키마 정의
// 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
}
});
console.log('1');
// 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 칼럼의 값이 없습니다.');
//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 스키마 정의됨');
//모델 정의
userModel = mongoose.model("users3", userSchema);
console.log('user3 모델 정의됨 3 ');
}
//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);
});
}
// 사용자 인증
var authUser = function (database, id, password, callback) {
console.log('authUser 함수 호출됨');
//ID로 검색
userModel.findById(id, function (err, results) {
if (err) {
callback(err, null);
return;
}
console.log('ID : %s로 검색 결과 ', id);
console.log(results);
if (results.length > 0) {
console.log('ID와 일치하는 사용자 찾음');
//비밀번호 확인
var user = new userModel({id : id});
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);
}
//비밀번호 확인
/*if (results[0]._doc.password == password) {
console.log('비밀번호 일치함');
callback(null, results);
} else {
console.log('비밀번호 일치하지 않음');
callback(null, null);
}*/
} else {
console.log('ID와 일치하는 사용자 못찾음');
callback(null, null);
}
});
//id랑 비번으로 인증여부 확인
/* userModel.find({"id":id, "password":password}, function(err,results){
if(err){
callback(err,null);
return;
}
console.log('id :%s, password: %s 로 검색한 결과', id, password);
console.dir(results);
if(results.length > 0){
console.log('일치하는 ㅅ 찾음');
callback(null, results);
}else{
console.log('일치하는 사람 없음');
callback(null,null);
}
}); */
}
// 사용자 추가
var addUser = function (database, id, password, name, callback) {
console.log('adduser 호출됨 ' + id);
// userModel 인스턴스 생성
var user = new userModel({
"id": id,
"password": password,
"name": name
});
user.save(function (err, user) {
if (err) {
callback(err, null);
return;
}
console.log('사용자 데이터 추가함');
callback(null, user);
});
}
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;
//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();
}
});
//사용자 추가 라우팅 함수
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;
console.log('요청 파라미터 : ' + paramId + ', ' + paramPassword + ', ' + paramName);
//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();
}
})
router.route('/process/listuser').post(function (req, res) {
console.log('/process/listuser 호출됨');
// db 연결되면
if (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();
}
});
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();
});
반응형
댓글