Soru Mongoose şifresi karmaşası


MongoDB'ye MongoDB kullanarak bir Hesabı kaydetmenin iyi bir yolunu arıyorum.

Benim sorunum: Şifre eşzamansız bir şekilde karma. Bir setter burada çalışmayacak çünkü sadece senkron çalışıyor.

2 yolu düşündüm:

  • Modelin bir örneğini oluşturun ve geri çağrısına kaydedin. Özet fonksiyonu.

  • 'Kaydetme' üzerinde bir ön kanca oluşturma

Bu problemde iyi bir çözüm var mı?


29
2018-01-29 16:55


Menşei




Cevaplar:


Mongodb blogu, kullanıcı kimlik doğrulamasının nasıl uygulanacağını gösteren mükemmel bir gönderiye sahiptir.

http://blog.mongodb.org/post/32866457221/password-authentication-with-mongoose-part-1

Aşağıdaki doğrudan yukarıdaki bağlantıdan kopyalanır:

Kullanıcı modeli

var mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    bcrypt = require('bcrypt'),
    SALT_WORK_FACTOR = 10;

var UserSchema = new Schema({
    username: { type: String, required: true, index: { unique: true } },
    password: { type: String, required: true }
});


UserSchema.pre('save', function(next) {
    var user = this;

    // only hash the password if it has been modified (or is new)
    if (!user.isModified('password')) return next();

    // generate a salt
    bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
        if (err) return next(err);

        // hash the password using our new salt
        bcrypt.hash(user.password, salt, function(err, hash) {
            if (err) return next(err);

            // override the cleartext password with the hashed one
            user.password = hash;
            next();
        });
    });
});

UserSchema.methods.comparePassword = function(candidatePassword, cb) {
    bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
        if (err) return cb(err);
        cb(null, isMatch);
    });
};

module.exports = mongoose.model('User', UserSchema);

kullanım

var mongoose = require(mongoose),
    User = require('./user-model');

var connStr = 'mongodb://localhost:27017/mongoose-bcrypt-test';
mongoose.connect(connStr, function(err) {
    if (err) throw err;
    console.log('Successfully connected to MongoDB');
});

// create a user a new user
var testUser = new User({
    username: 'jmar777',
    password: 'Password123';
});

// save user to database
testUser.save(function(err) {
    if (err) throw err;
});

// fetch user and test password verification
User.findOne({ username: 'jmar777' }, function(err, user) {
    if (err) throw err;

    // test a matching password
    user.comparePassword('Password123', function(err, isMatch) {
        if (err) throw err;
        console.log('Password123:', isMatch); // -> Password123: true
    });

    // test a failing password
    user.comparePassword('123Password', function(err, isMatch) {
        if (err) throw err;
        console.log('123Password:', isMatch); // -> 123Password: false
    });
});

87
2018-01-30 01:48



Sadece mongoose docs bir 'güncelleme' ile (bu, başlangıçta yaptım), bunu yapmaya çalışın ve başarısız olabilir birisi için bir not: Öncesi ve sonrası () kancalar güncelleme (), findOneAndUpdate (), vb üzerinde yürütülmez . - k00k
Doğru. Yapabilecekleriniz ayrı bir find () ve daha sonra save () fonksiyonudur? - Willem Mulder


Mongoose resmi çözümü, modelin konfüzyona neden olabilen confirmPass yöntemini kullanmadan önce kaydedilmesini gerektirir. Aşağıdakiler sizin için çalışır mı? (Bcrypt yerine scrypt kullanıyorum).

userSchema.virtual('pass').set(function(password) {
    this._password = password;
});

userSchema.pre('save', function(next) {
    if (this._password === undefined)
        return next();

    var pwBuf = new Buffer(this._password);
    var params = scrypt.params(0.1);
    scrypt.hash(pwBuf, params, function(err, hash) {
        if (err)
            return next(err);
        this.pwHash = hash;
        next();
    });
});

userSchema.methods.verifyPass = function(password, cb) {
    if (this._password !== undefined)
        return cb(null, this._password === password);

    var pwBuf = new Buffer(password);
    scrypt.verify(this.pwHash, pwBuf, function(err, isMatch) {
        return cb(null, !err && isMatch);
    });
};

2
2018-06-11 16:42





Bence bu kullanıcı Mongoose ve bcrypt tarafından iyi bir yoldur!

Kullanıcı modeli

/**
 * Module dependences
*/

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const bcrypt = require('bcrypt');
const SALT_WORK_FACTOR = 10;

// define User Schema
const UserSchema = new Schema({
    username: {
        type: String,
        unique: true,
        index: {
            unique: true
        }
    },
    hashed_password: {
        type: String,
        default: ''
    }
});

// Virtuals
UserSchema
    .virtual('password')
    // set methods
    .set(function (password) {
        this._password = password;
    });

UserSchema.pre("save", function (next) {
    // store reference
    const user = this;
    if (user._password === undefined) {
        return next();
    }
    bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {
        if (err) console.log(err);
        // hash the password using our new salt
        bcrypt.hash(user._password, salt, function (err, hash) {
            if (err) console.log(err);
            user.hashed_password = hash;
            next();
        });
    });
});

/**
 * Methods
*/
UserSchema.methods = {
    comparePassword: function(candidatePassword, cb) {
        bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
            if (err) return cb(err);
            cb(null, isMatch);
        });
    };
}

module.exports = mongoose.model('User', UserSchema);

kullanım

signup: (req, res) => {
    let newUser = new User({
        username: req.body.username,
        password: req.body.password
    });
    // save user
    newUser.save((err, user) => {
        if (err) throw err;
        res.json(user);
    });
}

Sonuç

Sonuç


2
2018-01-31 07:57





Bulduğum bazı araştırmalardan sonra, kanca kullanmak daha iyi olurdu

http://mongoosejs.com/docs/middleware.html

nerede söylüyor:

Kullanım Durumları:

eşzamansız varsayılanlar

Bu çözümü tercih ediyorum çünkü bunu kapatabilir ve bir hesabın yalnızca bir şifre ile kaydedilebildiğinden emin olabilirim.


0
2018-01-29 18:40





Sanalları ve örnek yöntemlerini kullanarak bunu yapmanın başka bir yolu:

/**
 * Virtuals
 */
schema.virtual('clean_password')
    .set(function(clean_password) {
        this._password = clean_password;
        this.password = this.encryptPassword(clean_password);
    })
    .get(function() {
        return this._password;
    });

schema.methods = {

    /**
     * Authenticate - check if the passwords are the same
     *
     * @param {String} plainText
     * @return {Boolean}
     * @api public
     */
    authenticate: function(plainPassword) {
        return bcrypt.compareSync(plainPassword, this.password);
    },

    /**
     * Encrypt password
     *
     * @param {String} password
     * @return {String}
     * @api public
     */
    encryptPassword: function(password) {
        if (!password)
            return '';

        return bcrypt.hashSync(password, 10);
    }
};

Sadece modelinizi kaydedin, sanal işini yapacak.

var user = {
    username: "admin",
    clean_password: "qwerty"
}

User.create(user, function(err,doc){});

0
2018-02-01 22:07