简体   繁体   English

Nodejs、bcrypt 异步、猫鼬登录

[英]Nodejs, bcrypt async, mongoose login

I have the following code for the user model我有以下用户模型的代码

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
}

})

Then for hashing the password i have this code然后为了散列密码,我有这个代码

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();

})

Then for checking the hash against the input value from user i have the following code然后为了检查来自用户的输入值哈希值,我有以下代码

userSchema.statics.comparePassword = function(password){
    let user = this;
    return bcrypt.compareAsync(password, user.password)
}

So when it comes to the usage of all of these pieces of code i have the following因此,当涉及到所有这些代码段的使用时,我有以下几点

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"
        })
     }
}

So I've tried searching on google and on this forum to find the answers but everything seems to be outdated or not working particularly for my situation.因此,我尝试在 google 和此论坛上搜索以找到答案,但一切似乎都已过时或不适用于我的情况。 This code always sends "The bid deal happened", i've tried to debug it from all sides but its still unsuccessful.此代码总是发送“投标交易发生”,我试图从各个方面对其进行调试,但仍然没有成功。

The question is how to make it work?问题是如何让它发挥作用? so that i can compare the passwords in the right way这样我就可以以正确的方式比较密码

PS I've tried changing from compareAsync to compareSync, shows no effect PS我试过从compareAsync更改为compareSync,显示没有效果

You encrypt the password when the value is changed, but not when you insert a new mongo document, you can check this with document.isNew .您在更改值时加密密码,但在插入新的 mongo 文档时不加密,您可以使用document.isNew进行检查。

I have updated your save method to the follow.我已将您的保存方法更新为以下内容。

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();
    }
});

Also, Schema.statics is used to serve static methods.此外, Schema.statics用于提供static方法。 The this context will not return the user, thus making this.password undefined. this上下文不会返回用户,从而使this.password未定义。 To populate the instances of your schema with methods, you have to append them to the Schema.methods object.要使用方法填充架构实例,您必须将它们附加到Schema.methods对象。

I have used bcrypt.compare in the past, I dont know if bcrypt.compareAsync is a valid method because the first one is already async.我过去用过bcrypt.compare ,我不知道bcrypt.compareAsync是否是一个有效的方法,因为第一个已经是异步的。 And if it was async, it wouldnt directly return a value.如果它是异步的,它就不会直接返回一个值。 Compare requires a callback.比较需要回调。

UsersSchema.methods.comparePassword = function (password, callback) {
    bcrypt.compare(password, this.password, (err, isMatch) => callback(err, isMatch));
};

To compare the password, u can do something like the following:要比较密码,您可以执行以下操作:

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
            }
        });
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM