Javascript Nodejs、bcrypt异步、mongoose登录

Javascript Nodejs、bcrypt异步、mongoose登录,javascript,node.js,mongodb,mongoose,postman,Javascript,Node.js,Mongodb,Mongoose,Postman,我为用户模型提供了以下代码 const userSchema = mongoose.Schema({ _id: mongoose.Schema.Types.ObjectId, username: { type: String, required: true, trim: true, minlength: 3, }, email: { type: String, required: true }, password: { type: St

我为用户模型提供了以下代码

const userSchema = mongoose.Schema({

_id: mongoose.Schema.Types.ObjectId,
username: {
    type: String,
    required: true,
    trim: true,
    minlength: 3,

},
email: {
    type: String,
    required: true
},
password: {
    type: String,
    required: true
}

})
然后对密码进行哈希运算,我有以下代码

UserSchema.pre('save', function (next) {


if (this.isModified('password')){

    bcrypt.genSalt(10, (err, salt)=>{

        bcrypt.hash(this.password, salt, (err, hash)=>{
            this.password = hash;
            next();
        })

    });
}
next();

})
然后,为了对照用户的输入值检查散列,我有以下代码

userSchema.statics.comparePassword = function(password){
    let user = this;
    return bcrypt.compareAsync(password, user.password)
}
因此,当谈到所有这些代码的用法时,我有以下几点

async loginUser(req, res) {
    try{
        const {email, password} = req.body
        const user = await User.findOne({
            email: req.body.email
        })
        if(!user){
            return res.status(403).send({
                error: "Incorrect details email"
            })
        }
        const isPassValid = await user.comparePassword(password)
       }catch(err){
        res.status(403).send({
            error: "The bid deal happened"
        })
     }
}
所以我试着在谷歌和这个论坛上搜索答案,但一切似乎都过时了,或者对我的情况不起作用。这段代码总是发送“出价交易发生了”,我试着从各个方面调试它,但仍然失败

问题是如何让它工作?这样我就可以用正确的方式比较密码了


p.S我已尝试将compareAsync更改为compareAsync,但没有显示任何效果

如果在更改值时加密密码,但在插入新的mongo文档时加密密码,则可以使用
document.isNew
进行检查

我已将您的保存方法更新为以下内容

UsersSchema.pre('save', function (next) {
    let user = this;

    if (this.isModified('password') || this.isNew) {
        bcrypt.genSalt(10, (err, salt) => {
            if (err) {
                return next(err);
            }

            bcrypt.hash(user.password, salt, (err, hash) => {
                if (err) {
                    return next(err);
                }

                user.password = hash;
                next();
            });
        });
    } else {
        next();
    }
});
另外,
Schema.statics
用于提供
static
方法。
this
上下文不会返回用户,因此使得
this.password
未定义。要用方法填充模式的实例,必须将它们附加到
schema.methods
对象中

我以前使用过
bcrypt.compare
,我不知道
bcrypt.compareAsync
是否有效,因为第一个方法已经是异步的。如果它是异步的,它不会直接返回值。比较需要回调

UsersSchema.methods.comparePassword = function (password, callback) {
    bcrypt.compare(password, this.password, (err, isMatch) => callback(err, isMatch));
};
要比较密码,您可以执行以下操作:

const { email, password } = req.body

User.findOne({
    email: email,
}, (err, user) => {
    if (err) throw err;

    if (user) {
        user.comparePassword(password, (err, match) => {
            if (match && !err) {
                // match
            }
        });
    }
});

这看起来不完整,请尝试打开
set DEBUG=*&&node
,console.log了解更多信息,并使用node inspect逐步调试。。关于如何使用mongoose等登录用户,有很多答案。。捕捉错误但输出没有有用信息的消息是错误的。。尝试将错误记录到控制台。您好,这一行“return bcrypt.compareAsync(password,user.password)”是compare还是compareSync?did console.log(bcrypt.compareSync(password,user.password)),但没有显示任何内容,改为“compare”没有显示任何内容。compare函数使用第三个参数,即回调bcrypt.compare(password,user.password,function(err,res){return res;});我用callback进行了尝试,它不会改变任何东西,谢谢你,只需要从静态变为方法,它就工作了。我只是更喜欢异步等待而不是到处回调函数:)