User.js 3.54 KB
// monggoDB Model and Schema
const mongoose = require('mongoose');
// bcrypt 가져옴
const bcrypt = require('bcrypt')
// bcrypt 사용하기 위해 salt를 생성하고 그걸 이용해 암호화 시킴
const saltRounds = 10   // salt를 몇글자 할 건지

const jwt = require('jsonwebtoken');
const moment = require("moment");

const userSchema = mongoose.Schema({
    name: {
        type:String,
        maxlength:50
    },
    email: {
        type:String,
        trim:true,
        unique: 1 
    },
    password: {
        type: String,
        minglength: 3
    },
    lastname: {
        type:String,
        maxlength: 50
    },
    role : {
        type:Number, // Number==1 이면 관리자, number==0 이면 일반 유저
        default: 0 // default는 0
    },
    image: String,
    token : {
        type: String,
    },
    tokenExp :{
        type: Number
    }
})

// index.js의 app.post('/register', (req, res)에 있는
// user model에 user 정보를 저장하기 전에 무엇을 한다는 것
// function( next )를 해서 얘네가 끝난 다음에 다음걸 실행해라~
userSchema.pre('save', function( next ) {
    var user = this;
    
    if(user.isModified('password')){    // password를 변경할 때만 적용되도록..
        
        // 비밀번호 암호화 (https://www.npmjs.com/package/bcrypt 에서 가져옴)
        bcrypt.genSalt(saltRounds, (err, salt) =>  // salt를 만드는 함수
        {
            if(err) return next(err)  // 에러 나면 return err
            bcrypt.hash(user.password, salt, (err, hash) => {   // bcrypt.hash(암호화되지 않은 pw, salt, function(err, 암호화된 비밀번호))
                if(err) return next(err)    // 에러 나면 return err
                user.password = hash    // 성공하면 user.password를 hash로 교체
                next() 
            })
        })
    } else {
        next()
    }
});

userSchema.methods.comparePassword = function(plainPassword,cb){

    // 1. plainPassword가 1234567    암호화된 비밀번호 가 같은지 체크해야함
    // 그러면 plainPassword도 암호화해서 비교해야함. (복호화 할 수 없기 때문에)
    bcrypt.compare(plainPassword, this.password, function(err, isMatch)
    {                                            // 에러가 나면 err callback, 아니면 isMatch
        if(err)     return cb(err);
        cb(null, isMatch);
    })
}

userSchema.methods.generateToken = function(cb) {
    var user = this;
    // jsonwebtoken을 이용해서 token 생성
    var token = jwt.sign(user._id.toHexString(), 'secretToken')    //database에 있는 id라서 _id
    var oneHour = moment().add(1, 'hour').valueOf();

    user.tokenExp = oneHour;
    user.token = token;
    user.save(function (err, user){
        if(err) return cb(err)// 에러가 있다면 callback으로 에러 전달
        cb(null, user)    // 에러가 없다면 err는 없고 user정보만 전달
    })
}

userSchema.statics.findByToken = function (token, cb) {
    var user = this;

    // 1. 토큰을 decoding
    jwt.verify(token, 'secretToken', function(err, decoded) {
    // 2. 유저 아이디를 이용해서 유저를 찾은 다음에 클라이언트에서 가져온 토큰과 DB에 보관된 토큰이 일치하는지 확인.
    user.findOne({"_id": decoded, "token": token}, function(err, user){ // findOne :: mongoDB에 이미 있는 method
        // 에러가 나면
        if(err) return cb(err);
        // 에러가 안나면
        cb(null, user)
    })    
})
}

const User = mongoose.model('User', userSchema);

module.exports = { User }